std.http.Client: fix redirects

This commit is contained in:
Andrew Kelley 2025-05-05 18:07:52 -07:00
parent b3df9d4bf9
commit af4bb996f0
4 changed files with 13 additions and 8 deletions

View File

@ -410,14 +410,14 @@ pub const Reader = struct {
var head_end: usize = 0;
while (true) {
if (head_end >= in.buffer.len) return error.HttpHeadersOversize;
const buf = in.peekGreedy(head_end + 1) catch |err| switch (err) {
in.fillMore() catch |err| switch (err) {
error.EndOfStream => switch (head_end) {
0 => return error.HttpConnectionClosing,
else => return error.HttpRequestTruncated,
},
error.ReadFailed => return error.ReadFailed,
};
head_end += hp.feed(buf[head_end..]);
head_end += hp.feed(in.bufferContents()[head_end..]);
if (hp.state == .finished) {
reader.head_buffer = in.steal(head_end);
reader.state = .received_head;

View File

@ -1078,6 +1078,7 @@ pub const Request = struct {
_ = reader.discardRemaining() catch |err| switch (err) {
error.ReadFailed => return r.reader.body_err.?,
};
r.reader.restituteHeadBuffer();
}
const new_uri = r.uri.resolveInPlace(location.len, aux_buf) catch |err| switch (err) {
error.UnexpectedCharacter => return error.HttpRedirectLocationInvalid,
@ -1124,6 +1125,10 @@ pub const Request = struct {
const new_connection = try r.client.connect(new_host, uriPort(new_uri, protocol), protocol);
r.uri = new_uri;
r.connection = new_connection;
r.reader = .{
.in = &new_connection.reader,
.state = .ready,
};
r.redirect_behavior.subtractOne();
}

View File

@ -219,6 +219,7 @@ pub const Request = struct {
};
pub fn iterateHeaders(r: *Request) http.HeaderIterator {
assert(r.server.reader.state == .received_head);
return http.HeaderIterator.init(r.server.reader.head_buffer);
}
@ -230,13 +231,11 @@ pub const Request = struct {
"TRansfer-encoding:\tdeflate, chunked \r\n" ++
"connectioN:\t keep-alive \r\n\r\n";
var br: std.io.BufferedReader = undefined;
br.initFixed(@constCast(request_bytes));
var server: Server = .{
.reader = .{
.in = &br,
.state = .ready,
.in = undefined,
.state = .received_head,
.head_buffer = @constCast(request_bytes),
},
.out = undefined,
};

View File

@ -1158,7 +1158,8 @@ test "redirect to different connection" {
const connection = try net_server.accept();
defer connection.stream.close();
const new_loc = try std.fmt.bufPrint(&send_buffer, "http://127.0.0.1:{d}/ok", .{
var loc_buf: [50]u8 = undefined;
const new_loc = try std.fmt.bufPrint(&loc_buf, "http://127.0.0.1:{d}/ok", .{
global.other_port.?,
});