receiveHead
If handling redirects and the request has no payload, then this function will automatically follow redirects.
If a request payload is present, then this function will error with
error.RedirectRequiresResend.
This function takes an auxiliary buffer to store the arbitrarily large URI which may need to be merged with the previous URI, and that data needs to survive across different connections, which is where the input buffer lives.
redirect_buffer must outlive accesses to Request.uri. If this
buffer capacity would be exceeded, error.HttpRedirectLocationOversize
is returned instead. This buffer may be empty if no redirects are to be
handled.
If this fails with error.ReadFailed then the Connection.getReadError
method of r.connection can be used to get more detailed information.
Function parameters
Parameters
- r:*Request
- redirect_buffer:[]u8
A Least-Recently-Used cache of open connections to be reused.
Types
- ConnectionPool
- A Least-Recently-Used cache of open connections to be reused.
Release all associated resources with the client.
Functions
- deinit
- Release all associated resources with the client.
- initDefaultProxies
- Populates `http_proxy` and `https_proxy` via standard proxy environment variables.
- connectTcp
- Reuses a `Connection` if one matching `host` and `port` is already open.
- connectUnix
- Connect to `path` as a unix domain socket.
- connectProxied
- Connect to `proxied_host:proxied_port` using the specified proxy with HTTP
- connect
- Connect to `host:port` using the specified protocol.
- request
- Open a connection to the host specified by `uri` and prepare to send a HTTP request.
- fetch
- Perform a one-shot HTTP request with the provided options.
Error sets in this namespace
Error Sets
= std.options.http_disable_tls
Values
- disable_tls
- = std.options.http_disable_tls
Source
Implementation
pub fn receiveHead(r: *Request, redirect_buffer: []u8) ReceiveHeadError!Response {
var aux_buf = redirect_buffer;
while (true) {
const head_buffer = try r.reader.receiveHead();
const response: Response = .{
.request = r,
.head = Response.Head.parse(head_buffer) catch return error.HttpHeadersInvalid,
};
const head = &response.head;
if (head.status == .@"continue") {
if (r.handle_continue) continue;
r.response_transfer_encoding = head.transfer_encoding;
r.response_content_length = head.content_length;
return response; // we're not handling the 100-continue
}
// This while loop is for handling redirects, which means the request's
// connection may be different than the previous iteration. However, it
// is still guaranteed to be non-null with each iteration of this loop.
const connection = r.connection.?;
if (r.method == .CONNECT and head.status.class() == .success) {
// This connection is no longer doing HTTP.
connection.closing = false;
r.response_transfer_encoding = head.transfer_encoding;
r.response_content_length = head.content_length;
return response;
}
connection.closing = !head.keep_alive or !r.keep_alive;
// Any response to a HEAD request and any response with a 1xx
// (Informational), 204 (No Content), or 304 (Not Modified) status
// code is always terminated by the first empty line after the
// header fields, regardless of the header fields present in the
// message.
if (r.method == .HEAD or head.status.class() == .informational or
head.status == .no_content or head.status == .not_modified)
{
r.response_transfer_encoding = head.transfer_encoding;
r.response_content_length = head.content_length;
return response;
}
if (head.status.class() == .redirect and r.redirect_behavior != .unhandled) {
if (r.redirect_behavior == .not_allowed) {
// Connection can still be reused by skipping the body.
const reader = r.reader.bodyReader(&.{}, head.transfer_encoding, head.content_length);
_ = reader.discardRemaining() catch |err| switch (err) {
error.ReadFailed => connection.closing = true,
};
return error.TooManyHttpRedirects;
}
try r.redirect(head, &aux_buf);
try r.sendBodiless();
continue;
}
if (!r.accept_encoding[@intFromEnum(head.content_encoding)])
return error.HttpContentEncodingUnsupported;
r.response_transfer_encoding = head.transfer_encoding;
r.response_content_length = head.content_length;
return response;
}
}