@@ -79,23 +79,34 @@ pub const HttpResponse = struct {
7979 status_code : u16 ,
8080 content_type : []const u8 ,
8181 body : []const u8 ,
82+ location : ? []const u8 = null ,
8283 allocator : std.mem.Allocator ,
8384
8485 pub fn deinit (self : * HttpResponse ) void {
8586 self .allocator .free (self .body );
87+ if (self .location ) | loc | self .allocator .free (loc );
8688 }
8789
8890 /// Format the response as a raw HTTP response string.
8991 pub fn toHttp (self : * const HttpResponse , allocator : std.mem.Allocator ) ! []u8 {
9092 const status_text = switch (self .status_code ) {
9193 200 = > "OK" ,
94+ 301 = > "Moved Permanently" ,
9295 400 = > "Bad Request" ,
9396 404 = > "Not Found" ,
9497 405 = > "Method Not Allowed" ,
9598 500 = > "Internal Server Error" ,
9699 else = > "Unknown" ,
97100 };
98101
102+ if (self .location ) | loc | {
103+ return try std .fmt .allocPrint (
104+ allocator ,
105+ "HTTP/1.1 {d} {s}\r \n Location: {s}\r \n Content-Length: 0\r \n Connection: close\r \n \r \n " ,
106+ .{ self .status_code , status_text , loc },
107+ );
108+ }
109+
99110 return try std .fmt .allocPrint (
100111 allocator ,
101112 "HTTP/1.1 {d} {s}\r \n Content-Type: {s}\r \n Content-Length: {d}\r \n Cache-Control: no-cache, no-store\r \n Connection: close\r \n \r \n {s}" ,
@@ -239,6 +250,26 @@ pub const AutoconfigServer = struct {
239250 }
240251 }
241252
253+ // CalDAV/CardDAV well-known discovery (RFC 6764) - any method
254+ if (std .mem .startsWith (u8 , path , "/.well-known/caldav" )) {
255+ return HttpResponse {
256+ .status_code = 301 ,
257+ .content_type = "text/plain" ,
258+ .body = try self .allocator .dupe (u8 , "" ),
259+ .location = try self .allocator .dupe (u8 , "/calendars/" ),
260+ .allocator = self .allocator ,
261+ };
262+ }
263+ if (std .mem .startsWith (u8 , path , "/.well-known/carddav" )) {
264+ return HttpResponse {
265+ .status_code = 301 ,
266+ .content_type = "text/plain" ,
267+ .body = try self .allocator .dupe (u8 , "" ),
268+ .location = try self .allocator .dupe (u8 , "/addressbooks/" ),
269+ .allocator = self .allocator ,
270+ };
271+ }
272+
242273 // Method not allowed for known paths
243274 if (std .ascii .eqlIgnoreCase (path , "/autodiscover/autodiscover.xml" )) {
244275 return HttpResponse {
0 commit comments