HTTP Core

repository·master·Indexed 19 days ago

https://github.com/encode/httpcore

A minimal, low-level HTTP client designed as a foundational networking layer for other libraries. It provides thread-safe and task-safe connection pooling, support for HTTP/1.1 and HTTP/2, and both synchronous and asynchronous interfaces (asyncio, trio, anyio). HTTP Core focuses strictly on sending requests and managing connection pools, omitting high-level features like redirect handling, cookie management, and JSON decoding.

Tokens
15.4K
Snippets
45
Records
75
Agent score
67%

What's inside httpcore

  1. What is HTTPCore?

    master

    HTTPCore is a minimal, low-level HTTP client designed for one purpose: sending HTTP requests. It avoids high-level abstractions like redirect handling, multipart uploads, authentication, caching, or JSON decoding.

    Key Features:

    • Sending HTTP requests.
    • Thread-safe and task-safe connection pooling.
    • HTTP(S) proxy and SOCKS proxy support.
    • Support for HTTP/1.1 and HTTP/2.
    • Both synchronous and asynchronous interfaces.
    • Async backend support for asyncio and trio.
  2. What is HTTP Core and when to use it

    master

    HTTP Core is a minimal, low-level HTTP client designed to do one thing: send HTTP requests. It provides a clear interface split between networking code and client logic.

    Key Features:

    • Thread-safe / task-safe connection pooling.
    • HTTP(S) proxy & SOCKS proxy support.
    • Supports HTTP/1.1 and HTTP/2.
    • Provides both sync and async interfaces (asyncio and trio).

    What it does NOT do: HTTP Core does not provide high-level abstractions. It does not handle:

    • Redirects
    • Multipart uploads
    • Authentication header building
    • Transparent HTTP caching
    • URL parsing
    • Session cookie handling
    • Content/charset decoding or JSON handling
    • Environment-based configuration defaults

    When to use it: You likely do not want to use HTTP Core directly for standard application development. It is intended as a reusable low-level library for other packages to build upon (e.g., httpx). It is most appropriate if you are building something like a proxy service where you need the lowest possible level of control.

  3. Understand HTTP connections in httpcore

    master
    In httpcore, connections are the low-level abstractions used to manage the lifecycle of an HTTP session. The library provides different connection classes depending on the protocol version required. While users typically interact with higher-level clients, understanding these connection types is essential for low-level protocol control.
  4. Manage AsyncConnectionPool lifespans

    master

    It is strongly recommended to use the context manager style (async with) to manage the lifespan of an AsyncConnectionPool. This ensures connections are properly closed.

    To benefit from connection pooling, instantiate a single pool in this style and pass it throughout your application.

    Warning: Do not rely on garbage collection to close async pools. Unlike synchronous code, the asynchronous __del__ method cannot run within the async context, which can lead to unterminated TCP connections. If you cannot use a context manager, you must explicitly call await http.aclose().

    async with httpcore.AsyncConnectionPool() as http:
        ...
    
    # Or manually if context manager is not possible:
    try:
        http = httpcore.AsyncConnectionPool()
        ...
    finally:
        await http.aclose()
  5. How network backends work in httpcore

    master
    A network backend is the API layer where httpcore interacts with the network. It handles low-level operations like opening TCP connections, socket stream operations (reading, writing, closing), and SSL/TLS upgrades. httpcore provides several implementations to support different runtime contexts (synchronous, asyncio, trio) and testing scenarios (mocking).
  6. Understand HTTP/2 header mapping in httpcore

    master

    To maintain a consistent API, httpcore uses HTTP/1.1 semantics for all requests and responses, even when using HTTP/2. The library maps these to HTTP/2 pseudo-headers internally.

    Request Headers

    • :method, :path, and :scheme: These are handled via the request.method and request.url attributes.
    • :authority: Mapped to the standard Host header. httpcore automatically populates the Host header from the URL if not explicitly provided.
    • Transfer-Encoding: chunked: In HTTP/1.1, this indicates a streaming body. In HTTP/2, streaming is handled via frames. httpcore uses this header in its API to represent streaming, but it is only actually sent over the wire if the connection is HTTP/1.1. It is omitted automatically for HTTP/2 connections.

    Response Headers

    • :status: The HTTP/2 status pseudo-header is mapped to the response.status attribute in httpcore.
  7. How extensions work in httpcore

    master

    The httpcore request/response API is intentionally minimal. To handle features that fall outside the core HTTP exchange (like timeouts, tracing, or low-level network access), httpcore uses 'extensions'.

    Extensions are provided as a dict of optional additional information attached to both Request and Response objects. This allows the core API to remain simple while supporting advanced use cases.

    # Pseudo-code of the core model with extensions
    (
        status_code: int,
        headers: List[Tuple(bytes, bytes)],
        stream: Iterable[bytes],
        extensions: dict
    ) = handle_request(
        method: bytes,
        url: URL,
        headers: List[Tuple(bytes, bytes)],
        stream: Iterable[bytes],
        extensions: dict
    )
  8. Understand HTTP connection types

    master
    HTTP connections are categorized by protocol version. For synchronous operations, you can use httpcore.HTTPConnection, httpcore.HTTP11Connection, or httpcore.HTTP2Connection. For asynchronous operations, use the corresponding Async variants: httpcore.AsyncHTTPConnection, httpcore.AsyncHTTP11Connection, and httpcore.AsyncHTTP2Connection.
  9. Use ConnectionPool for efficient requests

    master

    While httpcore provides top-level convenience functions, you should use httpcore.ConnectionPool in practice to benefit from connection reuse. A ConnectionPool instance allows subsequent requests to the same host to reuse established connections, significantly reducing latency compared to the first request.

    Connection pools support the same .request() and .stream() APIs as the top-level functions.

    import httpcore
    
    # Instantiate a pool
    http = httpcore.ConnectionPool()
    
    # Use it to send requests
    r = http.request("GET", "https://www.example.com/")
    print(r)
  10. Negotiate HTTP/2 via ALPN or Prior Knowledge

    master

    HTTP/2 over HTTPS (ALPN)

    By default, httpcore uses ALPN (Application Layer Protocol Negotiation) to negotiate HTTP/2 during the SSL handshake. This is the standard behavior for most browsers and is the default for httpcore. Note that if you use http:// URLs, httpcore will default to HTTP/1.1.

    HTTP/2 over HTTP (Upgrade)

    httpcore does not support the Upgrade: h2c mechanism for HTTP/2 over plain HTTP.

    Prior Knowledge

    If you know a server supports HTTP/2 and want to bypass negotiation (ALPN or Upgrade), you can enforce HTTP/2 by disabling HTTP/1.1 support in the connection pool.

    import httpcore
    
    # Enforce HTTP/2 by disabling HTTP/1.1
    pool = httpcore.ConnectionPool(http1=False, http2=True)