2 releases
0.1.1 | Jan 1, 2021 |
---|---|
0.1.0 | Jan 1, 2021 |
#1282 in HTTP server
24KB
547 lines
Overcodes HTTP Server
This is a super simple HTTP server that doesn't get in the way.
It doesn't do much, but it doesn't hide much. Additional features are exposed through various modules, including:
- Setting/getting cookies
- Websockets
This library is async, but does not dictate whether you use tokio, async-std, or something else.
My goal is to write a HTTP library that isn't confusing, doesn't prevent anything (even if it may require a few extra lines to get my goal), and has reasonable performance.
Getting started
If you're up for it, look at examples/simple_server.rs, examples/websocket_server.rs, and examples/echo_server.rs. They'll be up-to-date, unlike this doc.
Add to Cargo.toml
oc_http = "0.1.0"
I use async-std because it's easy, plus logging stuff;
async-std = {version = "1.8.0", features = ["attributes"]}
log = "0.4"
env_logger = "0.8"
Create a server:
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();
}
Dependencies
~7MB
~139K SLoC