1 个不稳定版本
0.1.0 | 2024年1月6日 |
---|
#7 in #http-connection
用于acril
78KB
2K SLoC
流式异步HTTP 1.1解析器。
HTTP本质上是一个有状态的RPC协议,客户端和服务器通过编码和解码消息进行通信。
client
编码HTTP请求,解码HTTP响应。server
解码HTTP请求,编码HTTP响应。
客户端始终启动HTTP连接。HTTP连接的生存期如下
1. encode 2. decode
\ /
-> request ->
client server
<- response <-
/ \
4. decode 3. encode
示例
HTTP客户端
use async_std::net::TcpStream;
use http_types::{Method, Request, Url};
#[async_std::main]
async fn main() -> http_types::Result<()> {
let stream = TcpStream::connect("127.0.0.1:8080").await?;
let peer_addr = stream.peer_addr()?;
println!("connecting to {}", peer_addr);
let url = Url::parse(&format!("http://{}/foo", peer_addr))?;
let req = Request::new(Method::Get, url);
let res = async_h1::connect(stream.clone(), req).await?;
println!("{:?}", res);
Ok(())
}
HTTP服务器
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?;
task::spawn(async {
if let Err(err) = accept(stream).await {
eprintln!("{}", err);
}
});
}
Ok(())
}
// Take a TCP stream, and convert it into sequential HTTP request / response pairs.
async fn accept(stream: TcpStream) -> http_types::Result<()> {
println!("starting new connection from {}", stream.peer_addr()?);
async_h1::accept(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(())
}
依赖项
~16–29MB
~558K SLoC