2 unstable releases
0.2.0 | Feb 15, 2024 |
---|---|
0.1.0 | Feb 14, 2024 |
#1424 in HTTP server
23KB
417 lines
servt
a programmatic web server, with very few dependencies.
why
- many big frameworks are too heavy for small projects, or don't suit yours (or my!) development style
- so this is small, easy to use, but still powerful
features
async
- enabled by default, adds
smol
as a dependency (adds around 35 deps) - executes all requests by spawning a new task
- if not enabled, falls back to
std::thread
(which spawns a new thread for each request)
time
- enabled by default, adds
chrono
as a dependency (adds around 2 deps, as the features enabled are very few, namelyalloc
andnow
) - adds a
Date
header to all responses - this is technically required by the HTTP/1.1 spec, but the majority of clients will work without it
lib.rs
:
A simple, easy to use, and fast web server library for Rust.
Designed to be easy, simple and fast, though powerful enough to handle most use cases.
Features
- Simple and easy to use
- Multi-threaded (or async if you enable the async feature
- Redirects
- Custom error pages
- Custom routes (with query string and form parsing)
- 100-continue support
- Custom status codes
A few notes
- The server by default uses multithreading, but you can enable the async feature to use async instead.
- The Date header is included by default, but you can disable the time feature to exclude it (and save a couple of dependencies). If you don't enable it, bear in mind that is against the HTTP/1.1 spec, but most clients don't care, and thus it is included as an option in order to keep the library as lightweight as possible if configured that way.
- At the moment, the server does not support keep-alive connections, but it is planned for the future (along with possible HTTP/2 support).
- Deliberately does not support Last-Modified, If-Modified-Since, etc., because it is not designed to serve static files, but rather functions which are not trackable in the same way.
Ensure your callbacks don't panic
- If a callback panics, the mutex is poisoned and thus the server will error out with a 500 Internal Server Error on any subsequent requests to the route - therefore, ensure your callbacks don't panic (or handle any errors and return a 500 error).
Supported path formats
-
/path
-
/path/
-
/path?query=string
-
/path/?query=string
-
site.com/path
-
site.com/path/
-
site.com/path?query=string
-
site.com/path/?query=string
-
Note that the Host header is mandated by the HTTP/1.1 spec, but if a request is sent with HTTP 1.0, the server will not enforce it (else it will error out with a 400 Bad Request).
Examples
Basic 'Hello, World!' server
use servt::{Server, ParsedRequest};
let mut server = Server::new(8080, "localhost".to_string());
server.route("/", |req| ("Hello, World!".to_string(), 200));
server.run();
Example good practice form handling
use servt::{Server, ParsedRequest};
let mut server = Server::new(8080, "localhost".to_string());
server.route("/", |req| match req.form {
Some(form) => (format!("Hello, {}!", form.get("name").unwrap_or(&"World".to_string())), 200),
None => ("Hello, World!".to_string(), 200),
});
server.run();
Custom error pages
use servt::{Server, ParsedRequest};
let mut server = Server::new(8080, "localhost".to_string());
server.error(404, |_| ("Custom 404 page".to_string(), 404));
server.run();
Dependencies
~0.1–9MB
~89K SLoC