Module h2::server

source ·
Expand description

Server implementation of the HTTP/2 protocol.

§Getting started

Running an HTTP/2 server requires the caller to manage accepting the connections as well as getting the connections to a state that is ready to begin the HTTP/2 handshake. See here for more details.

This could be as basic as using Tokio’s TcpListener to accept connections, but usually it means using either ALPN or HTTP/1.1 protocol upgrades.

Once a connection is obtained, it is passed to handshake, which will begin the HTTP/2 handshake. This returns a future that completes once the handshake process is performed and HTTP/2 streams may be received.

handshake uses default configuration values. There are a number of settings that can be changed by using Builder instead.

§Inbound streams

The Connection instance is used to accept inbound HTTP/2 streams. It does this by implementing futures::Stream. When a new stream is received, a call to Connection::accept will return (request, response). The request handle (of type http::Request<RecvStream>) contains the HTTP request head as well as provides a way to receive the inbound data stream and the trailers. The response handle (of type SendResponse) allows responding to the request, stream the response payload, send trailers, and send push promises.

The send (SendStream) and receive (RecvStream) halves of the stream can be operated independently.

§Managing the connection

The Connection instance is used to manage connection state. The caller is required to call either Connection::accept or Connection::poll_close in order to advance the connection state. Simply operating on SendStream or RecvStream will have no effect unless the connection state is advanced.

It is not required to call both Connection::accept and Connection::poll_close. If the caller is ready to accept a new stream, then only Connection::accept should be called. When the caller does not want to accept a new stream, Connection::poll_close should be called.

The Connection instance should only be dropped once Connection::poll_close returns Ready. Once Connection::accept returns Ready(None), there will no longer be any more inbound streams. At this point, only Connection::poll_close should be called.

§Shutting down the server

Graceful shutdown of the server is not yet implemented.

§Example

A basic HTTP/2 server example that runs over TCP and assumes prior knowledge, i.e. both the client and the server assume that the TCP socket will use the HTTP/2 protocol without prior negotiation.

use h2::server;
use http::{Response, StatusCode};
use tokio::net::TcpListener;

#[tokio::main]
pub async fn main() {
    let mut listener = TcpListener::bind("127.0.0.1:5928").await.unwrap();

    // Accept all incoming TCP connections.
    loop {
        if let Ok((socket, _peer_addr)) = listener.accept().await {
            // Spawn a new task to process each connection.
            tokio::spawn(async {
                // Start the HTTP/2 connection handshake
                let mut h2 = server::handshake(socket).await.unwrap();
                // Accept all inbound HTTP/2 streams sent over the
                // connection.
                while let Some(request) = h2.accept().await {
                    let (request, mut respond) = request.unwrap();
                    println!("Received request: {:?}", request);

                    // Build a response with no body
                    let response = Response::builder()
                        .status(StatusCode::OK)
                        .body(())
                        .unwrap();

                    // Send the response back to the client
                    respond.send_response(response, true)
                        .unwrap();
                }

            });
        }
    }
}

Structs§

Enums§

Constants§

Functions§

  • Creates a new configured HTTP/2 server with default configuration values backed by io.