Commit 51451341bf

Andrew Kelley <andrew@ziglang.org>
2024-02-22 01:41:59
update standalone http test file to new API
1 parent 17291e0
Changed files (1)
test
standalone
test/standalone/http.zig
@@ -17,150 +17,145 @@ var gpa_client = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = 12 })
 const salloc = gpa_server.allocator();
 const calloc = gpa_client.allocator();
 
-fn handleRequest(res: *http.Server, listen_port: u16) !void {
+fn handleRequest(request: *http.Server.Request, listen_port: u16) !void {
     const log = std.log.scoped(.server);
 
-    log.info("{} {s} {s}", .{ res.request.method, @tagName(res.request.version), res.request.target });
+    log.info("{} {s} {s}", .{
+        request.head.method,
+        @tagName(request.head.version),
+        request.head.target,
+    });
 
-    if (res.request.expect) |expect| {
+    if (request.head.expect) |expect| {
         if (mem.eql(u8, expect, "100-continue")) {
-            res.status = .@"continue";
-            try res.send();
-            res.status = .ok;
+            @panic("test failure, didn't handle expect 100-continue");
         } else {
-            res.status = .expectation_failed;
-            try res.send();
-            return;
+            return request.respond("", .{
+                .status = .expectation_failed,
+            });
         }
     }
 
-    const body = try res.reader().readAllAlloc(salloc, 8192);
+    const body = try request.reader().readAllAlloc(salloc, 8192);
     defer salloc.free(body);
 
-    if (res.request.keep_alive) {
-        res.keep_alive = true;
-    }
-
-    if (mem.startsWith(u8, res.request.target, "/get")) {
-        if (std.mem.indexOf(u8, res.request.target, "?chunked") != null) {
-            res.transfer_encoding = .chunked;
-        } else {
-            res.transfer_encoding = .{ .content_length = 14 };
-        }
+    var send_buffer: [100]u8 = undefined;
+
+    if (mem.startsWith(u8, request.head.target, "/get")) {
+        var response = request.respondStreaming(.{
+            .send_buffer = &send_buffer,
+            .content_length = if (std.mem.indexOf(u8, request.head.target, "?chunked") == null)
+                14
+            else
+                null,
+            .respond_options = .{
+                .extra_headers = &.{
+                    .{ .name = "content-type", .value = "text/plain" },
+                },
+            },
+        });
+        const w = response.writer();
+        try w.writeAll("Hello, ");
+        try w.writeAll("World!\n");
+        try response.end();
+        // Writing again would cause an assertion failure.
+    } else if (mem.startsWith(u8, request.head.target, "/large")) {
+        var response = request.respondStreaming(.{
+            .send_buffer = &send_buffer,
+            .content_length = 14 * 1024 + 14 * 10,
+        });
 
-        res.extra_headers = &.{
-            .{ .name = "content-type", .value = "text/plain" },
-        };
+        try response.flush(); // Test an early flush to send the HTTP headers before the body.
 
-        try res.send();
-        if (res.request.method != .HEAD) {
-            try res.writeAll("Hello, ");
-            try res.writeAll("World!\n");
-            try res.finish();
-        } else {
-            try testing.expectEqual(res.writeAll("errors"), error.NotWriteable);
-        }
-    } else if (mem.startsWith(u8, res.request.target, "/large")) {
-        res.transfer_encoding = .{ .content_length = 14 * 1024 + 14 * 10 };
-
-        try res.send();
+        const w = response.writer();
 
         var i: u32 = 0;
         while (i < 5) : (i += 1) {
-            try res.writeAll("Hello, World!\n");
+            try w.writeAll("Hello, World!\n");
         }
 
-        try res.writeAll("Hello, World!\n" ** 1024);
+        try w.writeAll("Hello, World!\n" ** 1024);
 
         i = 0;
         while (i < 5) : (i += 1) {
-            try res.writeAll("Hello, World!\n");
+            try w.writeAll("Hello, World!\n");
         }
 
-        try res.finish();
-    } else if (mem.startsWith(u8, res.request.target, "/echo-content")) {
+        try response.end();
+    } else if (mem.startsWith(u8, request.head.target, "/echo-content")) {
         try testing.expectEqualStrings("Hello, World!\n", body);
-        try testing.expectEqualStrings("text/plain", res.request.content_type.?);
-
-        switch (res.request.transfer_encoding) {
-            .chunked => res.transfer_encoding = .chunked,
-            .none => {
-                res.transfer_encoding = .{ .content_length = 14 };
-                try testing.expectEqual(14, res.request.content_length.?);
+        try testing.expectEqualStrings("text/plain", request.head.content_type.?);
+
+        var response = request.respondStreaming(.{
+            .send_buffer = &send_buffer,
+            .content_length = switch (request.head.transfer_encoding) {
+                .chunked => null,
+                .none => len: {
+                    try testing.expectEqual(14, request.head.content_length.?);
+                    break :len 14;
+                },
             },
-        }
-
-        try res.send();
-        try res.writeAll("Hello, ");
-        try res.writeAll("World!\n");
-        try res.finish();
-    } else if (mem.eql(u8, res.request.target, "/redirect/1")) {
-        res.transfer_encoding = .chunked;
-
-        res.status = .found;
-        res.extra_headers = &.{
-            .{ .name = "location", .value = "../../get" },
-        };
-
-        try res.send();
-        try res.writeAll("Hello, ");
-        try res.writeAll("Redirected!\n");
-        try res.finish();
-    } else if (mem.eql(u8, res.request.target, "/redirect/2")) {
-        res.transfer_encoding = .chunked;
-
-        res.status = .found;
-        res.extra_headers = &.{
-            .{ .name = "location", .value = "/redirect/1" },
-        };
+        });
 
-        try res.send();
-        try res.writeAll("Hello, ");
-        try res.writeAll("Redirected!\n");
-        try res.finish();
-    } else if (mem.eql(u8, res.request.target, "/redirect/3")) {
-        res.transfer_encoding = .chunked;
+        try response.flush(); // Test an early flush to send the HTTP headers before the body.
+        const w = response.writer();
+        try w.writeAll("Hello, ");
+        try w.writeAll("World!\n");
+        try response.end();
+    } else if (mem.eql(u8, request.head.target, "/redirect/1")) {
+        var response = request.respondStreaming(.{
+            .send_buffer = &send_buffer,
+            .respond_options = .{
+                .status = .found,
+                .extra_headers = &.{
+                    .{ .name = "location", .value = "../../get" },
+                },
+            },
+        });
 
+        const w = response.writer();
+        try w.writeAll("Hello, ");
+        try w.writeAll("Redirected!\n");
+        try response.end();
+    } else if (mem.eql(u8, request.head.target, "/redirect/2")) {
+        try request.respond("Hello, Redirected!\n", .{
+            .status = .found,
+            .extra_headers = &.{
+                .{ .name = "location", .value = "/redirect/1" },
+            },
+        });
+    } else if (mem.eql(u8, request.head.target, "/redirect/3")) {
         const location = try std.fmt.allocPrint(salloc, "http://127.0.0.1:{d}/redirect/2", .{
             listen_port,
         });
         defer salloc.free(location);
 
-        res.status = .found;
-        res.extra_headers = &.{
-            .{ .name = "location", .value = location },
-        };
-
-        try res.send();
-        try res.writeAll("Hello, ");
-        try res.writeAll("Redirected!\n");
-        try res.finish();
-    } else if (mem.eql(u8, res.request.target, "/redirect/4")) {
-        res.transfer_encoding = .chunked;
-
-        res.status = .found;
-        res.extra_headers = &.{
-            .{ .name = "location", .value = "/redirect/3" },
-        };
-
-        try res.send();
-        try res.writeAll("Hello, ");
-        try res.writeAll("Redirected!\n");
-        try res.finish();
-    } else if (mem.eql(u8, res.request.target, "/redirect/invalid")) {
+        try request.respond("Hello, Redirected!\n", .{
+            .status = .found,
+            .extra_headers = &.{
+                .{ .name = "location", .value = location },
+            },
+        });
+    } else if (mem.eql(u8, request.head.target, "/redirect/4")) {
+        try request.respond("Hello, Redirected!\n", .{
+            .status = .found,
+            .extra_headers = &.{
+                .{ .name = "location", .value = "/redirect/3" },
+            },
+        });
+    } else if (mem.eql(u8, request.head.target, "/redirect/invalid")) {
         const invalid_port = try getUnusedTcpPort();
         const location = try std.fmt.allocPrint(salloc, "http://127.0.0.1:{d}", .{invalid_port});
         defer salloc.free(location);
 
-        res.status = .found;
-        res.extra_headers = &.{
-            .{ .name = "location", .value = location },
-        };
-        try res.send();
-        try res.finish();
+        try request.respond("", .{
+            .status = .found,
+            .extra_headers = &.{
+                .{ .name = "location", .value = location },
+            },
+        });
     } else {
-        res.status = .not_found;
-        try res.send();
+        try request.respond("", .{ .status = .not_found });
     }
 }
 
@@ -172,18 +167,15 @@ fn runServer(server: *std.net.Server) !void {
         var connection = try server.accept();
         defer connection.stream.close();
 
-        var res = http.Server.init(connection, .{
-            .client_header_buffer = &client_header_buffer,
-        });
+        var http_server = http.Server.init(connection, &client_header_buffer);
 
-        while (res.reset() != .closing) {
-            res.wait() catch |err| switch (err) {
-                error.HttpHeadersInvalid => continue :outer,
-                error.EndOfStream => continue,
-                else => return err,
+        while (http_server.state == .ready) {
+            var request = http_server.receiveHead() catch |err| switch (err) {
+                error.HttpConnectionClosing => continue :outer,
+                else => |e| return e,
             };
 
-            try handleRequest(&res, server.listen_address.getPort());
+            try handleRequest(&request, server.listen_address.getPort());
         }
     }
 }