No description
- Rust 100%
| .forgejo/workflows | ||
| src | ||
| .gitignore | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
estd-http
A standalone HTTP server and client library with routing, middleware, and Server-Sent Events support.
Built on estd patterns, with no external dependencies beyond estd and estd-tls.
Features
- HTTP Server: Async routing, middleware pipeline, connection handling
- HTTP Client: GET, POST, PUT, DELETE, PATCH with custom headers and body handling
- Routing: Path pattern matching with path parameters (e.g.,
/users/:id) - Middleware: Request/response processing pipeline with context propagation
- Server-Sent Events (SSE): Real-time event streaming to clients
- Zero External Dependencies: Only
estdandestd-tlsdependencies
Quick Start
HTTP Server
use estd_http::{Server, StatusCode, ResponseBuilder};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = Server::new("127.0.0.1:8080");
server.get("/", |_req, _ctx| {
Ok(ResponseBuilder::new()
.status(StatusCode::Ok)
.header("Content-Type", "text/html")
.body_str("<h1>Hello, World!</h1>")
.build())
})?;
server.listen()?;
Ok(())
}
HTTP Client
use estd_http::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let response = client.get("http://example.com/api/data")?;
println!("Status: {}", response.status);
println!("Body: {}", response.body_string()?);
Ok(())
}
Server-Sent Events
use estd_http::{SseEvent, ResponseBuilder, StatusCode};
let event = SseEvent::new()
.event("update")
.data("New data available")
.id("123");
let response = ResponseBuilder::new()
.status(StatusCode::Ok)
.header("Content-Type", "text/event-stream")
.body_str(event.to_sse_format())
.build();
Routing
The server supports simple path pattern matching:
server.get("/users/:id", |req, _ctx| {
// req.uri contains the matched path
// Pattern matching with :id parameter
Ok(ResponseBuilder::new()
.status(StatusCode::Ok)
.body_str("User details")
.build())
})?;
server.post("/api/data", |req, _ctx| {
let body = String::from_utf8(req.body)?;
// Handle POST request
Ok(ResponseBuilder::new()
.status(StatusCode::Created)
.build())
})?;
Middleware
Chain multiple middleware for request/response processing:
use estd_http::MiddlewareBuilder;
let middleware = MiddlewareBuilder::new()
.with_logging()
.with_cors()
.with_auth("secret-token".to_string())
.build();
Request Methods
client.get(url)- GET requestclient.post(url, body)- POST request with bodyclient.post_json(url, json_str)- POST with JSON content-typeclient.put(url, body)- PUT requestclient.delete(url)- DELETE request
Status Codes
The library provides typed status codes:
StatusCode::Ok(200)StatusCode::Created(201)StatusCode::BadRequest(400)StatusCode::Unauthorized(401)StatusCode::NotFound(404)StatusCode::InternalServerError(500)StatusCode::Custom(u16)for custom codes
Headers
Access and set HTTP headers with case-insensitive keys:
let mut headers = Headers::new();
headers.set("Content-Type", "application/json");
headers.set("Authorization", "Bearer token");
if let Some(value) = headers.get("content-type") {
println!("Content-Type: {}", value);
}
License
This project is licensed under the ISC License. See LICENSE for details.
Author
Damien FLETY