Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

http.h1

import http

http exposes this as http.h1, so import http is enough and the names are called as http.h1.*. import http.h1 reaches the same definitions directly.

HTTP/1.1 on the wire (RFC 9110 and RFC 9112): reading a request line and its headers, writing a status line and its headers, and the chunked transfer encoding.

This is the layer HttpServer and HttpClient sit on when the connection is not HTTP/2. DEFAULT_LIMITS is what stops a malformed or hostile peer from making the parser allocate without bound.

Constants

DEFAULT_LIMITS

http.h1.DEFAULT_LIMITS = {...}

SERVER_NAME

http.h1.SERVER_NAME = 'Zuri'

USER_AGENT

http.h1.USER_AGENT = 'Zuri/1.0'

Functions

parse_version()

http.h1.parse_version(text: string) -> string

Parses HTTP/1.1 into '1.1', rejecting anything that is not a version this module understands the framing of.

Parameters

  • text (string)

Returns string

Raises ProtocolError

read_request()

http.h1.read_request(connection, options: ?dict)

Reads one request off a connection: the request line, the header section, and enough framing information to read the body.

The body is not read. request.body_reader is left positioned at its first byte, so the caller decides whether to materialise it, stream it, or refuse it - which is the only way to answer a 10 GiB upload with a 413 instead of accepting it first.

Parameters

  • connection (Connection)
  • options (?dict) — any of max_line_size, max_header_size, max_header_count

Returns — ?HttpRequest: nil when the peer closed the connection cleanly between messages

Raises ProtocolError on a malformed message

Raises TooLargeError if a limit is exceeded

send_continue()

http.h1.send_continue(connection)

Sends a 100 Continue interim response, telling a client that asked with Expect: 100-continue to go ahead and send its body.

Parameters

  • connection (Connection)

should_keep_alive()

http.h1.should_keep_alive(request, response) -> bool

Whether the connection should be kept open after this exchange.

HTTP/1.1 keeps connections open unless told otherwise; HTTP/1.0 closes them unless told otherwise. Either side can ask to close, and either side asking is enough.

Parameters

  • request (HttpRequest)
  • response (HttpResponse)

Returns bool

write_response()

http.h1.write_response(connection, request, response, options: ?dict)

Writes a response to a connection and returns whether the connection is still usable afterwards.

Framing is decided here rather than by the caller, because it has to agree with the status, the method, and the kind of body:

  • a 1xx, 204 or 304, and any response to HEAD, sends no body at all no matter what the body holds;
  • a body of known size gets a Content-Length;
  • a streamed body gets chunked encoding on HTTP/1.1, and on HTTP/1.0 - which has no chunked encoding - is delimited by closing the connection.

Parameters

  • connection (Connection)
  • request (HttpRequest)
  • response (HttpResponse)
  • options (?dict) — server_name for the Server header, and keep_alive to force the connection decision

Returns — bool: whether the connection may be reused

Raises ConnectionError, TimeoutError

write_request()

http.h1.write_request(connection, request, options: ?dict)

Writes a request to a connection.

Parameters

  • connection (Connection)
  • request (HttpRequest)
  • options (?dict) — body (bytes), and origin_form (default true) to control whether the target is written as a path or as an absolute URL, which is what a request to a forward proxy needs

Raises ConnectionError, TimeoutError

read_response()

http.h1.read_response(connection, request, options: ?dict) -> HttpResponse

Reads a response off a connection.

Interim 1xx responses are consumed and skipped, since they are part of the exchange rather than its result. A 101 is returned as it is: that one is the result, and the caller is switching protocols on the strength of it.

Parameters

  • connection (Connection)
  • request (HttpRequest) — the request being answered; its method decides the response’s framing
  • options (?dict) — max_line_size, max_header_size, max_header_count, max_body_size, decode_content (default true), and stream (default false) to leave the body unread

Returns HttpResponse

Raises ProtocolError, TooLargeError, ConnectionError

Classes

ChunkWriter

class http.h1.ChunkWriter

The writer handed to a streaming response body.

write() sends data as it is produced, framed as chunked transfer encoding when that is how the response was framed, and raw otherwise. flush() pushes what has been written all the way to the socket, which is what makes a progress feed or a server-sent-event stream actually arrive rather than sit in a buffer.

Constructor

http.h1.ChunkWriter(connection, chunked)

Parameters

  • connection (Connection)
  • chunked (bool)

ChunkWriter.write()

http.h1.ChunkWriter.write(data)

Writes part of the body.

A zero-length write is dropped rather than sent, since a zero-length chunk is the end-of-body marker and sending one early would truncate the response.

Parameters

  • data (bytes|string)

ChunkWriter.flush()

http.h1.ChunkWriter.flush()

Pushes everything written so far out to the socket.

ChunkWriter.finish()

http.h1.ChunkWriter.finish(trailers)

Ends the body, writing the terminating chunk when the response is chunked. Called for you when the streaming handler returns.

Parameters

  • trailers (?Headers) — trailer fields to send after the last chunk; only meaningful for a chunked body, and only ever read by a client that announced TE: trailers

ChunkWriter.abort()

http.h1.ChunkWriter.abort()

2026, Richard Ore and Zuri contributors