Skip to content

fewensa/rttp

Repository files navigation

rttp

A small Rust HTTP workspace with a client crate (rttp_client) and a wrapper crate (rttp) that also provides a minimal blocking HTTP server.

Client

rttp_client supports plain HTTP by default. Optional features add async request APIs and TLS implementations:

name comment
async Async request APIs
http2 Prior-knowledge h2c GET over direct socket2 TCP connections
tls-native HTTPS with native-tls
tls-rustls HTTPS with rustls
[dependencies]
rttp_client = "0.2"

Direct TCP client connections are opened with socket2. SOCKS proxy handshakes are still delegated to the socks crate. HTTP/1.x chunked responses are decoded by the client, and response trailers are available through Response::trailers, Response::trailer, and Response::trailer_value. With the http2 feature enabled, emit_http2_prior_knowledge sends a minimal prior-knowledge h2c GET request over a direct socket2 TCP connection. TLS ALPN, proxy tunneling, request bodies, and general HTTP/2 multiplexing are not part of that initial client path.

use rttp_client::HttpClient;

let response = HttpClient::new()
  .get()
  .url("http://127.0.0.1:8080/health")
  .emit()?;
# Ok::<(), Box<dyn std::error::Error>>(())

Server

The rttp crate exposes rttp::Http::server, which creates a blocking HttpServer listener.

[dependencies]
rttp = "0.2"
use std::time::Duration;

use rttp::server::HttpResponse;

fn main() -> std::io::Result<()> {
  let server = rttp::Http::server("127.0.0.1:0")?
    .with_read_timeout(Some(Duration::from_secs(5)))
    .with_write_timeout(Some(Duration::from_secs(5)));
  println!("listening on {}", server.local_addr()?);

  server.accept_one(|request| {
    println!("{} {}", request.method(), request.target());
    HttpResponse::ok("hello")
      .header("Transfer-Encoding", "chunked")
      .header("Trailer", "X-Trace")
      .trailer("X-Trace", "abc")
  })
}

Use HttpServer::bind directly when you already want the server type, HttpServer::local_addr to read the bound address, accept_one for one connection, and serve_requests for a fixed number of sequential connections. Use with_read_timeout and with_write_timeout to apply socket-level timeouts to each accepted connection; pass None to leave the corresponding socket timeout unset. Add Transfer-Encoding: chunked to an HttpResponse to write the complete response body with HTTP/1.x chunked transfer framing instead of an automatic Content-Length; response trailers added with HttpResponse::trailer are written after the terminating zero-size chunk. Add a Trailer response header when advertising which trailer fields will follow. The listener path uses socket2.

The server is intentionally small: it handles blocking HTTP/1.x request parsing for local tests and simple embedded use. It accepts fixed Content-Length and chunked request bodies, exposes chunked request trailers, applies bounded request head/body validation, handles HEAD without writing a response body, honors Connection close/keep-alive semantics across a bounded serve_requests loop, writes response body framing and response trailers consistently, and accepts Expect: 100-continue. On the same socket2 listener, the accept path detects the HTTP/2 client preface and dispatches prior-knowledge h2c requests to a minimal single-stream handler. TLS ALPN and full HTTP/2 multiplexing remain outside this server path.

It is not a full RFC-covering web server and still does not implement server TLS or async accept loops.

About

http lib for rust

Resources

License

Stars

2 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors

Languages