[][src]Crate async_h1

Streaming async HTTP 1.1 parser.

At its core HTTP is a stateful RPC protocol, where a client and server communicate with one another by encoding and decoding messages between them.

  • client encodes HTTP requests, and decodes HTTP responses.
  • server decodes HTTP requests, and encodes HTTP responses.

A client always starts the HTTP connection. The lifetime of an HTTP connection looks like this:

1. encode            2. decode
        \            /
        -> request  ->
 client                server
        <- response <-
        /            \
4. decode            3. encode

See also async-tls, async-std.

Example

HTTP client

use async_h1::client;
use async_std::net::{TcpStream};
use http_types::{Error, Method, Request, Url};

#[async_std::main]
async fn main() -> Result<(), Error> {
    let stream = TcpStream::connect("127.0.0.1:8080").await?;
    let peer_addr = stream.peer_addr()?;
    println!("connecting to {}", peer_addr);

    for i in 0usize..2 {
        println!("making request {}/2", i + 1);
        let url = Url::parse(&format!("http://{}/foo", peer_addr)).unwrap();
        let req = Request::new(Method::Get, dbg!(url));
        let res = client::connect(stream.clone(), req).await?;
        println!("{:?}", res);
    }
    Ok(())
}

HTTP Server

use async_std::net::{TcpStream, TcpListener};
use async_std::prelude::*;
use async_std::task;
use http_types::{Response, StatusCode};

#[async_std::main]
async fn main() -> http_types::Result<()> {
    // Open up a TCP connection and create a URL.
    let listener = TcpListener::bind(("127.0.0.1", 8080)).await?;
    let addr = format!("http://{}", listener.local_addr()?);
    println!("listening on {}", addr);

    // For each incoming TCP connection, spawn a task and call `accept`.
    let mut incoming = listener.incoming();
    while let Some(stream) = incoming.next().await {
        let stream = stream?;
        let addr = addr.clone();
        task::spawn(async {
            if let Err(err) = accept(addr, stream).await {
                eprintln!("{}", err);
            }
        });
    }
    Ok(())
}

// Take a TCP stream, and convert it into sequential HTTP request / response pairs.
async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> {
    println!("starting new connection from {}", stream.peer_addr()?);
    async_h1::accept(&addr, stream.clone(), |_req| async move {
        let mut res = Response::new(StatusCode::Ok);
        res.insert_header("Content-Type", "text/plain")?;
        res.set_body("Hello");
        Ok(res)
    })
    .await?;
    Ok(())
}

Structs

ServerOptions

Configure the server.

Functions

accept

Accept a new incoming HTTP/1.1 connection.

accept_with_opts

Accept a new incoming HTTP/1.1 connection.

connect

Opens an HTTP/1.1 connection to a remote host.