authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-05-05 18:07:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:29-07:00
logaf4bb996f0e1f022c25a28db021a536b92e80bf3
treeabd7a475fe97249821ce5e9a5c87d43c8b550a44
parentb3df9d4bf91e4df6a643ab23c8ec44f239cd14b6

std.http.Client: fix redirects


4 files changed, 13 insertions(+), 8 deletions(-)

lib/std/http.zig+2-2
...@@ -410,14 +410,14 @@ pub const Reader = struct {...@@ -410,14 +410,14 @@ pub const Reader = struct {
410 var head_end: usize = 0;410 var head_end: usize = 0;
411 while (true) {411 while (true) {
412 if (head_end >= in.buffer.len) return error.HttpHeadersOversize;412 if (head_end >= in.buffer.len) return error.HttpHeadersOversize;
413 const buf = in.peekGreedy(head_end + 1) catch |err| switch (err) {413 in.fillMore() catch |err| switch (err) {
414 error.EndOfStream => switch (head_end) {414 error.EndOfStream => switch (head_end) {
415 0 => return error.HttpConnectionClosing,415 0 => return error.HttpConnectionClosing,
416 else => return error.HttpRequestTruncated,416 else => return error.HttpRequestTruncated,
417 },417 },
418 error.ReadFailed => return error.ReadFailed,418 error.ReadFailed => return error.ReadFailed,
419 };419 };
420 head_end += hp.feed(buf[head_end..]);420 head_end += hp.feed(in.bufferContents()[head_end..]);
421 if (hp.state == .finished) {421 if (hp.state == .finished) {
422 reader.head_buffer = in.steal(head_end);422 reader.head_buffer = in.steal(head_end);
423 reader.state = .received_head;423 reader.state = .received_head;
lib/std/http/Client.zig+5
...@@ -1078,6 +1078,7 @@ pub const Request = struct {...@@ -1078,6 +1078,7 @@ pub const Request = struct {
1078 _ = reader.discardRemaining() catch |err| switch (err) {1078 _ = reader.discardRemaining() catch |err| switch (err) {
1079 error.ReadFailed => return r.reader.body_err.?,1079 error.ReadFailed => return r.reader.body_err.?,
1080 };1080 };
1081 r.reader.restituteHeadBuffer();
1081 }1082 }
1082 const new_uri = r.uri.resolveInPlace(location.len, aux_buf) catch |err| switch (err) {1083 const new_uri = r.uri.resolveInPlace(location.len, aux_buf) catch |err| switch (err) {
1083 error.UnexpectedCharacter => return error.HttpRedirectLocationInvalid,1084 error.UnexpectedCharacter => return error.HttpRedirectLocationInvalid,
...@@ -1124,6 +1125,10 @@ pub const Request = struct {...@@ -1124,6 +1125,10 @@ pub const Request = struct {
1124 const new_connection = try r.client.connect(new_host, uriPort(new_uri, protocol), protocol);1125 const new_connection = try r.client.connect(new_host, uriPort(new_uri, protocol), protocol);
1125 r.uri = new_uri;1126 r.uri = new_uri;
1126 r.connection = new_connection;1127 r.connection = new_connection;
1128 r.reader = .{
1129 .in = &new_connection.reader,
1130 .state = .ready,
1131 };
1127 r.redirect_behavior.subtractOne();1132 r.redirect_behavior.subtractOne();
1128 }1133 }
11291134
lib/std/http/Server.zig+4-5
...@@ -219,6 +219,7 @@ pub const Request = struct {...@@ -219,6 +219,7 @@ pub const Request = struct {
219 };219 };
220220
221 pub fn iterateHeaders(r: *Request) http.HeaderIterator {221 pub fn iterateHeaders(r: *Request) http.HeaderIterator {
222 assert(r.server.reader.state == .received_head);
222 return http.HeaderIterator.init(r.server.reader.head_buffer);223 return http.HeaderIterator.init(r.server.reader.head_buffer);
223 }224 }
224225
...@@ -230,13 +231,11 @@ pub const Request = struct {...@@ -230,13 +231,11 @@ pub const Request = struct {
230 "TRansfer-encoding:\tdeflate, chunked \r\n" ++231 "TRansfer-encoding:\tdeflate, chunked \r\n" ++
231 "connectioN:\t keep-alive \r\n\r\n";232 "connectioN:\t keep-alive \r\n\r\n";
232233
233 var br: std.io.BufferedReader = undefined;
234 br.initFixed(@constCast(request_bytes));
235
236 var server: Server = .{234 var server: Server = .{
237 .reader = .{235 .reader = .{
238 .in = &br,236 .in = undefined,
239 .state = .ready,237 .state = .received_head,
238 .head_buffer = @constCast(request_bytes),
240 },239 },
241 .out = undefined,240 .out = undefined,
242 };241 };
lib/std/http/test.zig+2-1
...@@ -1158,7 +1158,8 @@ test "redirect to different connection" {...@@ -1158,7 +1158,8 @@ test "redirect to different connection" {
1158 const connection = try net_server.accept();1158 const connection = try net_server.accept();
1159 defer connection.stream.close();1159 defer connection.stream.close();
11601160
1161 const new_loc = try std.fmt.bufPrint(&send_buffer, "http://127.0.0.1:{d}/ok", .{1161 var loc_buf: [50]u8 = undefined;
1162 const new_loc = try std.fmt.bufPrint(&loc_buf, "http://127.0.0.1:{d}/ok", .{
1162 global.other_port.?,1163 global.other_port.?,
1163 });1164 });
11641165