HTTP/2
Implementation of RFC7541 and RFC9113. In other words, a low-level HTTP.
Passes the hpack-test-case
and the h2spec
test suites. Due to official deprecation, server push and prioritization are not supported.
Activation feature is called http2
.
Client Example
//! Fetches an URI using low-level HTTP/2 resources. //! //! This snippet requires ~25 dependencies and has an optimized binary size of ~700K. extern crate tokio; extern crate wtx; extern crate wtx_instances; use tokio::net::TcpStream; use wtx::{ http::{Method, ReqResBuffer, Request}, http2::{Http2Buffer, Http2ErrorCode, Http2Params, Http2Tokio}, misc::{from_utf8_basic, NoStdRng, Uri}, }; #[tokio::main] async fn main() -> wtx::Result<()> { let uri = Uri::new("http://www.example.com"); let (frame_reader, mut http2) = Http2Tokio::connect( Http2Buffer::new(NoStdRng::default()), Http2Params::default(), TcpStream::connect(uri.hostname_with_implied_port()).await?.into_split(), ) .await?; let _jh = tokio::spawn(frame_reader); let rrb = ReqResBuffer::default(); let mut stream = http2.stream().await?; stream.send_req(Request::http2(Method::Get, b"Hello!"), &uri.to_ref()).await?; let (res_rrb, opt) = stream.recv_res(rrb).await?; let _status_code = opt.unwrap(); println!("{}", from_utf8_basic(&res_rrb.data)?); http2.send_go_away(Http2ErrorCode::NoError).await; Ok(()) }
Server Example
//! Serves requests using low-level HTTP/2 resources along side self-made certificates. extern crate tokio; extern crate wtx; extern crate wtx_instances; use wtx::{ http::{LowLevelServer, ReqResBuffer, Request, Response, StatusCode}, http2::{Http2Buffer, Http2Params}, misc::{StdRng, TokioRustlsAcceptor}, }; #[tokio::main] async fn main() -> wtx::Result<()> { LowLevelServer::tokio_http2( &wtx_instances::host_from_args(), || Ok(((), Http2Buffer::new(StdRng::default()), Http2Params::default())), |error| eprintln!("{error}"), handle, || Ok(((), ReqResBuffer::default())), ( || { TokioRustlsAcceptor::without_client_auth() .build_with_cert_chain_and_priv_key(wtx_instances::CERT, wtx_instances::KEY) }, |acceptor| acceptor.clone(), |acceptor, stream| async move { Ok(tokio::io::split(acceptor.accept(stream).await?)) }, ), ) .await } async fn handle( _: (), _: (), mut req: Request<ReqResBuffer>, ) -> Result<Response<ReqResBuffer>, wtx::Error> { req.rrd.clear(); Ok(req.into_response(StatusCode::Ok)) }