authorgravatar for truemedian@gmail.comNameless <truemedian@gmail.com> 2023-10-07 20:05:04-05:00
committergravatar for truemedian@gmail.comNameless <truemedian@gmail.com> 2023-10-21 20:52:59-05:00
log544ed34d99f59a1b487341eaaa9610be44629924
tree4e14e3404ac1d3eb0ea12fcbd6b7b040a0c9cfb3
parentd4cf8ea0b7621f7757203ecdbaa760e99cbc455c
signaturelock-open Commit is signed but in an unrecognized format.

std.http.Server: improve documentation, do -> start

Response.do was renamed to Response.start to mimic the naming scheme in http.Client

3 files changed, 31 insertions(+), 17 deletions(-)

lib/std/http/Client.zig+1-1
......@@ -605,7 +605,7 @@ pub const Request = struct {
605605 raw_uri: bool = false,
606606 };
607607
608 /// Send the HTTP request to the server.
608 /// Send the HTTP request headers to the server.
609609 pub fn start(req: *Request, options: StartOptions) StartError!void {
610610 if (!req.method.requestHasBody() and req.transfer_encoding != .none) return error.UnsupportedTransferEncoding;
611611
lib/std/http/Server.zig+18-4
......@@ -14,7 +14,7 @@ allocator: Allocator,
1414
1515socket: net.StreamServer,
1616
17/// An interface to either a plain or TLS connection.
17/// An interface to a plain connection.
1818pub const Connection = struct {
1919 pub const buffer_size = std.crypto.tls.max_ciphertext_record_len;
2020 pub const Protocol = enum { plain };
......@@ -273,8 +273,13 @@ pub const Request = struct {
273273 target: []const u8,
274274 version: http.Version,
275275
276 /// The length of the request body, if known.
276277 content_length: ?u64 = null,
278
279 /// The transfer encoding of the request body, or .none if not present.
277280 transfer_encoding: http.TransferEncoding = .none,
281
282 /// The compression of the request body, or .identity (no compression) if not present.
278283 transfer_compression: http.ContentEncoding = .identity,
279284
280285 headers: http.Headers,
......@@ -311,6 +316,7 @@ pub const Response = struct {
311316 finished,
312317 };
313318
319 /// Free all resources associated with this response.
314320 pub fn deinit(res: *Response) void {
315321 res.connection.close();
316322
......@@ -386,10 +392,10 @@ pub const Response = struct {
386392 }
387393 }
388394
389 pub const DoError = Connection.WriteError || error{ UnsupportedTransferEncoding, InvalidContentLength };
395 pub const StartError = Connection.WriteError || error{ UnsupportedTransferEncoding, InvalidContentLength };
390396
391 /// Send the response headers.
392 pub fn do(res: *Response) DoError!void {
397 /// Send the HTTP response headers to the client.
398 pub fn start(res: *Response) StartError!void {
393399 switch (res.state) {
394400 .waited => res.state = .responded,
395401 .first, .start, .responded, .finished => unreachable,
......@@ -548,6 +554,7 @@ pub const Response = struct {
548554 return .{ .context = res };
549555 }
550556
557 /// Reads data from the response body. Must be called after `wait`.
551558 pub fn read(res: *Response, buffer: []u8) ReadError!usize {
552559 switch (res.state) {
553560 .waited, .responded, .finished => {},
......@@ -583,6 +590,7 @@ pub const Response = struct {
583590 return out_index;
584591 }
585592
593 /// Reads data from the response body. Must be called after `wait`.
586594 pub fn readAll(res: *Response, buffer: []u8) !usize {
587595 var index: usize = 0;
588596 while (index < buffer.len) {
......@@ -602,6 +610,7 @@ pub const Response = struct {
602610 }
603611
604612 /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent.
613 /// Must be called after `start` and before `finish`.
605614 pub fn write(res: *Response, bytes: []const u8) WriteError!usize {
606615 switch (res.state) {
607616 .responded => {},
......@@ -627,6 +636,8 @@ pub const Response = struct {
627636 }
628637 }
629638
639 /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent.
640 /// Must be called after `start` and before `finish`.
630641 pub fn writeAll(req: *Response, bytes: []const u8) WriteError!void {
631642 var index: usize = 0;
632643 while (index < bytes.len) {
......@@ -637,6 +648,7 @@ pub const Response = struct {
637648 pub const FinishError = WriteError || error{MessageNotCompleted};
638649
639650 /// Finish the body of a request. This notifies the server that you have no more data to send.
651 /// Must be called after `start`.
640652 pub fn finish(res: *Response) FinishError!void {
641653 switch (res.state) {
642654 .responded => res.state = .finished,
......@@ -651,6 +663,7 @@ pub const Response = struct {
651663 }
652664};
653665
666/// Create a new HTTP server.
654667pub fn init(allocator: Allocator, options: net.StreamServer.Options) Server {
655668 return .{
656669 .allocator = allocator,
......@@ -658,6 +671,7 @@ pub fn init(allocator: Allocator, options: net.StreamServer.Options) Server {
658671 };
659672}
660673
674/// Free all resources associated with this server.
661675pub fn deinit(server: *Server) void {
662676 server.socket.deinit();
663677}
test/standalone/http.zig+12-12
......@@ -29,11 +29,11 @@ fn handleRequest(res: *Server.Response) !void {
2929 if (res.request.headers.contains("expect")) {
3030 if (mem.eql(u8, res.request.headers.getFirstValue("expect").?, "100-continue")) {
3131 res.status = .@"continue";
32 try res.do();
32 try res.start();
3333 res.status = .ok;
3434 } else {
3535 res.status = .expectation_failed;
36 try res.do();
36 try res.start();
3737 return;
3838 }
3939 }
......@@ -54,7 +54,7 @@ fn handleRequest(res: *Server.Response) !void {
5454
5555 try res.headers.append("content-type", "text/plain");
5656
57 try res.do();
57 try res.start();
5858 if (res.request.method != .HEAD) {
5959 try res.writeAll("Hello, ");
6060 try res.writeAll("World!\n");
......@@ -65,7 +65,7 @@ fn handleRequest(res: *Server.Response) !void {
6565 } else if (mem.startsWith(u8, res.request.target, "/large")) {
6666 res.transfer_encoding = .{ .content_length = 14 * 1024 + 14 * 10 };
6767
68 try res.do();
68 try res.start();
6969
7070 var i: u32 = 0;
7171 while (i < 5) : (i += 1) {
......@@ -92,14 +92,14 @@ fn handleRequest(res: *Server.Response) !void {
9292 try testing.expectEqualStrings("14", res.request.headers.getFirstValue("content-length").?);
9393 }
9494
95 try res.do();
95 try res.start();
9696 try res.writeAll("Hello, ");
9797 try res.writeAll("World!\n");
9898 try res.finish();
9999 } else if (mem.eql(u8, res.request.target, "/trailer")) {
100100 res.transfer_encoding = .chunked;
101101
102 try res.do();
102 try res.start();
103103 try res.writeAll("Hello, ");
104104 try res.writeAll("World!\n");
105105 // try res.finish();
......@@ -110,7 +110,7 @@ fn handleRequest(res: *Server.Response) !void {
110110 res.status = .found;
111111 try res.headers.append("location", "../../get");
112112
113 try res.do();
113 try res.start();
114114 try res.writeAll("Hello, ");
115115 try res.writeAll("Redirected!\n");
116116 try res.finish();
......@@ -120,7 +120,7 @@ fn handleRequest(res: *Server.Response) !void {
120120 res.status = .found;
121121 try res.headers.append("location", "/redirect/1");
122122
123 try res.do();
123 try res.start();
124124 try res.writeAll("Hello, ");
125125 try res.writeAll("Redirected!\n");
126126 try res.finish();
......@@ -133,7 +133,7 @@ fn handleRequest(res: *Server.Response) !void {
133133 res.status = .found;
134134 try res.headers.append("location", location);
135135
136 try res.do();
136 try res.start();
137137 try res.writeAll("Hello, ");
138138 try res.writeAll("Redirected!\n");
139139 try res.finish();
......@@ -143,7 +143,7 @@ fn handleRequest(res: *Server.Response) !void {
143143 res.status = .found;
144144 try res.headers.append("location", "/redirect/3");
145145
146 try res.do();
146 try res.start();
147147 try res.writeAll("Hello, ");
148148 try res.writeAll("Redirected!\n");
149149 try res.finish();
......@@ -154,11 +154,11 @@ fn handleRequest(res: *Server.Response) !void {
154154
155155 res.status = .found;
156156 try res.headers.append("location", location);
157 try res.do();
157 try res.start();
158158 try res.finish();
159159 } else {
160160 res.status = .not_found;
161 try res.do();
161 try res.start();
162162 }
163163}
164164