Function receiveHead [src]

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.

Prototype

pub fn receiveHead(r: *Request, redirect_buffer: []u8) ReceiveHeadError!Response

Parameters

r: *Requestredirect_buffer: []u8

Possible Errors

CertificateBundleLoadFailure RequestError
ConnectionRefused ConnectTcpError
ConnectionResetByPeer ConnectTcpError
ConnectionTimedOut ConnectTcpError
HostLacksNetworkAddresses ConnectTcpError
HttpChunkInvalid
HttpChunkTruncated
HttpConnectionClosing HeadError

The client sent 0 bytes of headers before closing the stream. This happens when a keep-alive connection is finally closed.

HttpContentEncodingUnsupported
HttpHeadersInvalid

Server sent headers that did not conform to the HTTP protocol.

To find out more detailed diagnostics, http.Reader.head_buffer can be passed directly to Request.Head.parse.

HttpHeadersOversize HeadError

Too many bytes of HTTP headers.

The HTTP specification suggests to respond with a 431 status code before closing the connection.

HttpRedirectLocationInvalid
HttpRedirectLocationMissing
HttpRedirectLocationOversize
HttpRequestTruncated HeadError

Partial HTTP request was received but the connection was closed before fully receiving the headers.

NameServerFailure ConnectTcpError
NetworkUnreachable ConnectTcpError
OutOfMemory Error
ReadFailed HeadError

Transitive error occurred reading from in.

RedirectRequiresResend

This can be avoided by calling receiveHead before sending the request body.

TemporaryNameServerFailure ConnectTcpError
TlsInitializationFailed ConnectTcpError
TooManyHttpRedirects
UnexpectedConnectFailure ConnectTcpError
UnknownHostName ConnectTcpError
UnsupportedUriScheme RequestError
UriHostTooLong RequestError
UriMissingHost RequestError
WriteFailed

Sending the request failed. Error code can be found on the Connection object.

Source

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; } }