2 个版本

0.1.1 2021 年 1 月 1 日
0.1.0 2021 年 1 月 1 日

#1272HTTP 服务器

MIT 许可证

24KB
547

Overcodes HTTP 服务器

这是一个非常简单的 HTTP 服务器,不会妨碍你。

它做的事情不多,但也不隐藏太多。通过各种模块暴露了额外的功能,包括

  • 设置/获取 Cookie
  • WebSockets

这个库是异步的,但不强制你使用 tokio、async-std 或其他任何东西。

我的目标是编写一个不令人困惑的 HTTP 库,不阻止任何事情(即使这可能需要几行额外的代码来实现目标),并且有合理的性能。

入门

如果你有兴趣,请查看 examples/simple_server.rsexamples/websocket_server.rsexamples/echo_server.rs。与这个文档相比,它们将是最新的。

添加到 Cargo.toml

oc_http = "0.1.0"

我使用 async-std,因为它简单,还有日志功能;

async-std = {version = "1.8.0", features = ["attributes"]}
log = "0.4"
env_logger = "0.8"

创建服务器

use std::error::Error;
use log::warn;
use env_logger::Env;
use async_std::{
    task,
    io::{
        BufReader,
        BufWriter,
    },
    net::TcpListener,
};
use futures::{
    prelude::*,
    AsyncRead,
    AsyncWrite,
};

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // setup the logger
    env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
    // start the server; this uses standard stdlib-esque tools rather than saving a few
    // lines by just sending the ToSocketAddr item.
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    let mut incoming = listener.incoming();
    // Accepting incoming reqeusts
    while let Some(stream) = incoming.next().await {
        if let Ok(stream) = stream {
            task::spawn(handle_request(stream));
        }
    }
    Ok(())
}

async fn handle_request<S>(stream: S)
where S: AsyncRead + AsyncWrite + Clone + Unpin
{
    // parse the http request; prefer using BufWriter/BufReader for performance.
    let mut reader = BufReader::new(stream.clone());
    let mut writer = BufWriter::new(stream);
    // Read the request
    match oc_http::http(&mut reader).await {
        Ok(req) => req,
        Err(err) => {
            warn!("Error {}", err);
            return;
        },
    };
    oc_http::respond(&mut writer, oc_http::Response{
        code: 200,
        reason: "OK",
        headers: vec!(),
    }).await.unwrap();
    // after sending the HTTP header, we can write anything to the body
    writer.write(b"
<html>
    <body>
        <h1>Hello world!</h1>
    </body>
</html>
    ").await.unwrap();
    writer.flush().await.unwrap();
}

依赖项

~7MB
~139K SLoC