$ cargo run --bin client
$ cargo run --bin server
- More Security Checks (Request Size limits)
- Websockets
- websocket middleware
- websocket upgrade
- websocket frame parser
- websocket masking
- websocket chunked messages
- websocket frame builder
- Partial request parsing
- Stream Abstraction (Chunked encoding)
- Revisit low level parallel processing of incoming sockets
use anyhow::Result;
use webserver_from_scratch::{middleware, router::Router, HTTPServer, LogLevel, StatusCode};
fn main() -> Result<()> {
let mut server = HTTPServer::new();
server.loglevel(LogLevel::Off);
let hello_world_handler = middleware!(|ctx| {
let resp = b"<h1>Hello World</h1>";
ctx.response.content_type("text/html");
ctx.response.write(resp);
ctx.end();
});
let hello_handler = middleware!(|ctx| {
ctx.response.content_type("text/html");
ctx.response.write(b"<h1>Hello ");
let params = ctx.params.clone();
let name = params.get(":name");
let name = if let Some(name) = name {
name.value.as_bytes()
} else {
b"World"
};
ctx.response.write(name);
ctx.response.write(b"</h1>");
ctx.end();
});
server
.get("/", hello_world_handler)
.get("/:name", hello_handler);
server.any(
"*",
middleware!(|ctx| {
let resp = b"404";
ctx.response.status_code(StatusCode::NotFound);
ctx.response.write(resp);
}),
);
server.listen_blocking("[::1]:8080".parse().unwrap())
}
middleware!(|ctx| {
// User Code (can use .await)
})
{
let closure = |ctx: MiddlewareCtx| -> HandlerFut {
Box::pin(async move {
// We have to use a mutex for the request context since the
// borrow checker doesn't recognize that an async function has finished running and
let mut ctx = ctx.lock(); // will be locked after `ctx` is dropped at the end of this block
/// {User code}
Ok(()) // enable error catching by returning a result (enables using `?` for catching errors)
})
};
closure // return closure from this block
}