Skip to content

HTTP/2 Protocol ​

RFC 9113 defines HTTP/2, introducing a binary framing layer that multiplexes multiple concurrent request/response streams over a single TCP connection, eliminating head-of-line blocking at the transport layer.

Architecture ​

Unlike HTTP/1.x plaintext protocols, HTTP/2 is a binary framed protocol. All HTTP semantics (methods, status codes, URIs, and headers) remain identical, but messages are divided into discrete typed frames:

text
+-----------------------------------------------+
|                 Length (24)                   |
+---------------+---------------+---------------+
|   Type (8)    |   Flags (8)   |
+-+-------------+---------------+-------------------------------+
|R|                 Stream Identifier (31)                      |
+=+=============================================================+
|                   Frame Payload (0...)                      ...
+---------------------------------------------------------------+

Core Frame Types ​

  • HEADERS: Transmits request and response headers with HPACK compression.
  • DATA: Transmits body payloads (payload chunks can be interleaved across active streams).
  • SETTINGS: Negotiates connection parameters (initial window size, max frame size, max concurrent streams).
  • WINDOW_UPDATE: Implements stream-level and connection-level credit flow control.
  • PING: Measures round-trip time and verifies connection liveness.
  • GOAWAY: Signals graceful connection shutdown.
  • RST_STREAM: Cancels an individual stream without closing the underlying TCP socket.

HPACK Header Compression (RFC 7541) ​

HTTP/2 uses HPACK compression to drastically reduce header overhead:

  • Static Table: Pre-defined table of 61 common header names and values.
  • Dynamic Table: Stores newly encountered headers in an in-memory sliding window.
  • Huffman Encoding: Compresses individual header literals with static Huffman codes.

Prior Knowledge vs ALPN ​

HTTPX supports two methods for establishing HTTP/2 connections:

  1. h2 via TLS ALPN: During TLS 1.3/1.2 handshake, the client requests h2 and the server agrees.
  2. h2c via Prior Knowledge: On cleartext TCP, the client sends the 24-byte magic connection preface (PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n) followed immediately by a SETTINGS frame.

Client Usage Example ​

zig
const std = @import("std");
const httpx = @import("httpx");

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    const io = std.Io.Threaded.global_single_threaded.io();

    var client = httpx.Client.init(allocator, io, .{});
    defer client.deinit();

    var response = try client.get("https://nghttp2.org/httpbin/get", .{
        .httpVersion = .http2,
    });
    defer response.deinit();

    std.debug.print("HTTP/2 Status: {d}\n", .{response.status});
}

Released under the MIT License.