authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-21 17:41:59-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-23 02:37:11-07:00
log51451341bf06f949fd3b4cec0c5c302cecf2aa8c
tree61c13b08ec590e40508f10623080091f8303ef72
parent17291e072b86b7f2bcb775907cf0984e281662a2

update standalone http test file to new API


1 files changed, 109 insertions(+), 117 deletions(-)

test/standalone/http.zig+109-117
......@@ -17,150 +17,145 @@ var gpa_client = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = 12 })
1717const salloc = gpa_server.allocator();
1818const calloc = gpa_client.allocator();
1919
20fn handleRequest(res: *http.Server, listen_port: u16) !void {
20fn handleRequest(request: *http.Server.Request, listen_port: u16) !void {
2121 const log = std.log.scoped(.server);
2222
23 log.info("{} {s} {s}", .{ res.request.method, @tagName(res.request.version), res.request.target });
23 log.info("{} {s} {s}", .{
24 request.head.method,
25 @tagName(request.head.version),
26 request.head.target,
27 });
2428
25 if (res.request.expect) |expect| {
29 if (request.head.expect) |expect| {
2630 if (mem.eql(u8, expect, "100-continue")) {
27 res.status = .@"continue";
28 try res.send();
29 res.status = .ok;
31 @panic("test failure, didn't handle expect 100-continue");
3032 } else {
31 res.status = .expectation_failed;
32 try res.send();
33 return;
33 return request.respond("", .{
34 .status = .expectation_failed,
35 });
3436 }
3537 }
3638
37 const body = try res.reader().readAllAlloc(salloc, 8192);
39 const body = try request.reader().readAllAlloc(salloc, 8192);
3840 defer salloc.free(body);
3941
40 if (res.request.keep_alive) {
41 res.keep_alive = true;
42 }
43
44 if (mem.startsWith(u8, res.request.target, "/get")) {
45 if (std.mem.indexOf(u8, res.request.target, "?chunked") != null) {
46 res.transfer_encoding = .chunked;
47 } else {
48 res.transfer_encoding = .{ .content_length = 14 };
49 }
42 var send_buffer: [100]u8 = undefined;
43
44 if (mem.startsWith(u8, request.head.target, "/get")) {
45 var response = request.respondStreaming(.{
46 .send_buffer = &send_buffer,
47 .content_length = if (std.mem.indexOf(u8, request.head.target, "?chunked") == null)
48 14
49 else
50 null,
51 .respond_options = .{
52 .extra_headers = &.{
53 .{ .name = "content-type", .value = "text/plain" },
54 },
55 },
56 });
57 const w = response.writer();
58 try w.writeAll("Hello, ");
59 try w.writeAll("World!\n");
60 try response.end();
61 // Writing again would cause an assertion failure.
62 } else if (mem.startsWith(u8, request.head.target, "/large")) {
63 var response = request.respondStreaming(.{
64 .send_buffer = &send_buffer,
65 .content_length = 14 * 1024 + 14 * 10,
66 });
5067
51 res.extra_headers = &.{
52 .{ .name = "content-type", .value = "text/plain" },
53 };
68 try response.flush(); // Test an early flush to send the HTTP headers before the body.
5469
55 try res.send();
56 if (res.request.method != .HEAD) {
57 try res.writeAll("Hello, ");
58 try res.writeAll("World!\n");
59 try res.finish();
60 } else {
61 try testing.expectEqual(res.writeAll("errors"), error.NotWriteable);
62 }
63 } else if (mem.startsWith(u8, res.request.target, "/large")) {
64 res.transfer_encoding = .{ .content_length = 14 * 1024 + 14 * 10 };
65
66 try res.send();
70 const w = response.writer();
6771
6872 var i: u32 = 0;
6973 while (i < 5) : (i += 1) {
70 try res.writeAll("Hello, World!\n");
74 try w.writeAll("Hello, World!\n");
7175 }
7276
73 try res.writeAll("Hello, World!\n" ** 1024);
77 try w.writeAll("Hello, World!\n" ** 1024);
7478
7579 i = 0;
7680 while (i < 5) : (i += 1) {
77 try res.writeAll("Hello, World!\n");
81 try w.writeAll("Hello, World!\n");
7882 }
7983
80 try res.finish();
81 } else if (mem.startsWith(u8, res.request.target, "/echo-content")) {
84 try response.end();
85 } else if (mem.startsWith(u8, request.head.target, "/echo-content")) {
8286 try testing.expectEqualStrings("Hello, World!\n", body);
83 try testing.expectEqualStrings("text/plain", res.request.content_type.?);
84
85 switch (res.request.transfer_encoding) {
86 .chunked => res.transfer_encoding = .chunked,
87 .none => {
88 res.transfer_encoding = .{ .content_length = 14 };
89 try testing.expectEqual(14, res.request.content_length.?);
87 try testing.expectEqualStrings("text/plain", request.head.content_type.?);
88
89 var response = request.respondStreaming(.{
90 .send_buffer = &send_buffer,
91 .content_length = switch (request.head.transfer_encoding) {
92 .chunked => null,
93 .none => len: {
94 try testing.expectEqual(14, request.head.content_length.?);
95 break :len 14;
96 },
9097 },
91 }
92
93 try res.send();
94 try res.writeAll("Hello, ");
95 try res.writeAll("World!\n");
96 try res.finish();
97 } else if (mem.eql(u8, res.request.target, "/redirect/1")) {
98 res.transfer_encoding = .chunked;
99
100 res.status = .found;
101 res.extra_headers = &.{
102 .{ .name = "location", .value = "../../get" },
103 };
104
105 try res.send();
106 try res.writeAll("Hello, ");
107 try res.writeAll("Redirected!\n");
108 try res.finish();
109 } else if (mem.eql(u8, res.request.target, "/redirect/2")) {
110 res.transfer_encoding = .chunked;
111
112 res.status = .found;
113 res.extra_headers = &.{
114 .{ .name = "location", .value = "/redirect/1" },
115 };
98 });
11699
117 try res.send();
118 try res.writeAll("Hello, ");
119 try res.writeAll("Redirected!\n");
120 try res.finish();
121 } else if (mem.eql(u8, res.request.target, "/redirect/3")) {
122 res.transfer_encoding = .chunked;
100 try response.flush(); // Test an early flush to send the HTTP headers before the body.
101 const w = response.writer();
102 try w.writeAll("Hello, ");
103 try w.writeAll("World!\n");
104 try response.end();
105 } else if (mem.eql(u8, request.head.target, "/redirect/1")) {
106 var response = request.respondStreaming(.{
107 .send_buffer = &send_buffer,
108 .respond_options = .{
109 .status = .found,
110 .extra_headers = &.{
111 .{ .name = "location", .value = "../../get" },
112 },
113 },
114 });
123115
116 const w = response.writer();
117 try w.writeAll("Hello, ");
118 try w.writeAll("Redirected!\n");
119 try response.end();
120 } else if (mem.eql(u8, request.head.target, "/redirect/2")) {
121 try request.respond("Hello, Redirected!\n", .{
122 .status = .found,
123 .extra_headers = &.{
124 .{ .name = "location", .value = "/redirect/1" },
125 },
126 });
127 } else if (mem.eql(u8, request.head.target, "/redirect/3")) {
124128 const location = try std.fmt.allocPrint(salloc, "http://127.0.0.1:{d}/redirect/2", .{
125129 listen_port,
126130 });
127131 defer salloc.free(location);
128132
129 res.status = .found;
130 res.extra_headers = &.{
131 .{ .name = "location", .value = location },
132 };
133
134 try res.send();
135 try res.writeAll("Hello, ");
136 try res.writeAll("Redirected!\n");
137 try res.finish();
138 } else if (mem.eql(u8, res.request.target, "/redirect/4")) {
139 res.transfer_encoding = .chunked;
140
141 res.status = .found;
142 res.extra_headers = &.{
143 .{ .name = "location", .value = "/redirect/3" },
144 };
145
146 try res.send();
147 try res.writeAll("Hello, ");
148 try res.writeAll("Redirected!\n");
149 try res.finish();
150 } else if (mem.eql(u8, res.request.target, "/redirect/invalid")) {
133 try request.respond("Hello, Redirected!\n", .{
134 .status = .found,
135 .extra_headers = &.{
136 .{ .name = "location", .value = location },
137 },
138 });
139 } else if (mem.eql(u8, request.head.target, "/redirect/4")) {
140 try request.respond("Hello, Redirected!\n", .{
141 .status = .found,
142 .extra_headers = &.{
143 .{ .name = "location", .value = "/redirect/3" },
144 },
145 });
146 } else if (mem.eql(u8, request.head.target, "/redirect/invalid")) {
151147 const invalid_port = try getUnusedTcpPort();
152148 const location = try std.fmt.allocPrint(salloc, "http://127.0.0.1:{d}", .{invalid_port});
153149 defer salloc.free(location);
154150
155 res.status = .found;
156 res.extra_headers = &.{
157 .{ .name = "location", .value = location },
158 };
159 try res.send();
160 try res.finish();
151 try request.respond("", .{
152 .status = .found,
153 .extra_headers = &.{
154 .{ .name = "location", .value = location },
155 },
156 });
161157 } else {
162 res.status = .not_found;
163 try res.send();
158 try request.respond("", .{ .status = .not_found });
164159 }
165160}
166161
......@@ -172,18 +167,15 @@ fn runServer(server: *std.net.Server) !void {
172167 var connection = try server.accept();
173168 defer connection.stream.close();
174169
175 var res = http.Server.init(connection, .{
176 .client_header_buffer = &client_header_buffer,
177 });
170 var http_server = http.Server.init(connection, &client_header_buffer);
178171
179 while (res.reset() != .closing) {
180 res.wait() catch |err| switch (err) {
181 error.HttpHeadersInvalid => continue :outer,
182 error.EndOfStream => continue,
183 else => return err,
172 while (http_server.state == .ready) {
173 var request = http_server.receiveHead() catch |err| switch (err) {
174 error.HttpConnectionClosing => continue :outer,
175 else => |e| return e,
184176 };
185177
186 try handleRequest(&res, server.listen_address.getPort());
178 try handleRequest(&request, server.listen_address.getPort());
187179 }
188180 }
189181}