Skip to content

SYSTEM Cited by 1 source

hyper

hyper is the most widely used HTTP library in the Rust ecosystem, providing both client and server implementations for HTTP/1.1 and HTTP/2. It is the foundation for higher-level frameworks like Axum and Warp, and is used by Cloudflare's Images service for managing HTTP connections at the edge.

Architecture

hyper's HTTP/1 connection lifecycle is driven by a state machine in dispatch.rs. The main loop:

  1. poll_read — reads incoming request data from the socket.
  2. poll_write — encodes the response into an internal write buffer.
  3. poll_flush — moves buffered data from the internal buffer to the kernel's socket outbound buffer.
  4. wants_read_again — determines whether the connection has more work to do.

When all work is complete, poll_shutdown is called to close the socket with shutdown(fd, SHUT_WR).

Key Insight: Encoding vs Flushing

hyper marks a response as "written" as soon as the full response body is buffered internally (Writing::Closed), not when all bytes have been flushed to the socket. In most cases this distinction is invisible because the flush completes in one pass. Under backpressure (socket buffer full), however, the flush needs multiple wakeups — and if the pending state is not properly propagated, data loss can occur (Source: sources/2026-06-22-cloudflare-how-we-found-a-bug-in-the-hyper-http-library).

Notable Bug: Premature Shutdown Race Condition

A race condition existed across hyper versions 0.14.x through 1.8.x where poll_flush returning Poll::Pending was silently discarded via let _ = self.poll_flush(cx)?. Under backpressure, this caused the dispatch loop to exit and trigger socket shutdown while megabytes of data remained in hyper's internal buffer. Fixed in PR #4018 by adding a flush guard in poll_shutdown.

Seen In

Last updated · 559 distilled / 1,651 read