authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-21 00:44:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-23 02:37:11-07:00
log2e7d8062cad12510c37bf1b882058c8fc869b6c0
tree5d8aab46c64acfda8175b9e3cde8018616612563
parentb4b9f6aa4a5bfd6a54b59444f3e1a3706358eb76

std.http.Server: fix seeing phantom request


1 files changed, 19 insertions(+), 3 deletions(-)

lib/std/http/Server.zig+19-3
......@@ -31,7 +31,7 @@ pub const State = enum {
3131
3232/// Initialize an HTTP server that can respond to multiple requests on the same
3333/// connection.
34/// The returned `Server` is ready for `readRequest` to be called.
34/// The returned `Server` is ready for `receiveHead` to be called.
3535pub fn init(connection: net.Server.Connection, read_buffer: []u8) Server {
3636 return .{
3737 .connection = connection,
......@@ -51,6 +51,12 @@ pub const ReceiveHeadError = error{
5151 HttpHeadersInvalid,
5252 /// A low level I/O error occurred trying to read the headers.
5353 HttpHeadersUnreadable,
54 /// Partial HTTP request was received but the connection was closed before
55 /// fully receiving the headers.
56 HttpRequestTruncated,
57 /// The client sent 0 bytes of headers before closing the stream.
58 /// In other words, a keep-alive connection was finally closed.
59 HttpConnectionClosing,
5460};
5561
5662/// The header bytes reference the read buffer that Server was initialized with
......@@ -63,8 +69,11 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request {
6369 // In case of a reused connection, move the next request's bytes to the
6470 // beginning of the buffer.
6571 if (s.next_request_start > 0) {
66 if (s.read_buffer_len > s.next_request_start) rebase(s, 0);
67 s.next_request_start = 0;
72 if (s.read_buffer_len > s.next_request_start) {
73 rebase(s, 0);
74 } else {
75 s.read_buffer_len = 0;
76 }
6877 }
6978
7079 var hp: http.HeadParser = .{};
......@@ -82,6 +91,13 @@ pub fn receiveHead(s: *Server) ReceiveHeadError!Request {
8291 return error.HttpHeadersOversize;
8392 const read_n = s.connection.stream.read(buf) catch
8493 return error.HttpHeadersUnreadable;
94 if (read_n == 0) {
95 if (s.read_buffer_len > 0) {
96 return error.HttpRequestTruncated;
97 } else {
98 return error.HttpConnectionClosing;
99 }
100 }
85101 s.read_buffer_len += read_n;
86102 const bytes = buf[0..read_n];
87103 const end = hp.feed(bytes);