HTTP/2 in-depth server design

submited by
Style Pass
2024-10-25 00:00:04

This is a high-level description of nim-hyperx, an HTTP/2 server and client. It may be useful for HTTP/2 implementers and the curious.

This is not an overview of the HTTP/2 protocol. I won’t go over frame types, stream states, flow-control, nor the spec in general.

These are independent asynchronous tasks that run concurrently with user code, meaning the user cannot block the receiving of frames. However, if the user stops consuming streams, data frames will eventually stop arriving due to flow-control limits, while other types of frames will continue to be processed. (Of course, they could also block the async/await event loop—cough, cough.)

Data communication is typically handled through asynchronous bounded queues. These queues have the advantage of providing backpressure: once the queue is full, it must be awaited until an element is consumed before adding another. In this case, upstream components must wait for frames to be processed before placing a received frame into the queue. The queue also provides a buffer, allowing one frame to be processed while another is being received. This is also helpful during small spikes of received frames.

Frames are continuously read from the socket. This does all kind of frame checks, such as verifying frame size, payload value, and padding size. Continuation frames are received until the end, but the stream of continuations may not terminate, so it must be limited to an arbitrary total size (not specified in the spec).

Leave a Comment