Struct servlin::HttpServerBuilder
source · pub struct HttpServerBuilder { /* private fields */ }Expand description
Builds an HTTP server.
Implementations§
source§impl HttpServerBuilder
impl HttpServerBuilder
sourcepub fn new() -> Self
pub fn new() -> Self
Makes a new builder these default settings:
- Listens on 127.0.0.1
- Picks a random port
- 100 max connections
- 64 KiB small body length
- no cache dir, server rejects large request bodies
Examples found in repository?
More examples
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/subscribe");
let event_sender_thread_permit = Permit::new();
let state = Arc::new(State::new());
let state_clone = state.clone();
std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.spawn_and_join(request_handler),
)
.unwrap();
}78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}sourcepub fn listen_addr(self, addr: SocketAddr) -> Self
pub fn listen_addr(self, addr: SocketAddr) -> Self
Examples found in repository?
More examples
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/subscribe");
let event_sender_thread_permit = Permit::new();
let state = Arc::new(State::new());
let state_clone = state.clone();
std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.spawn_and_join(request_handler),
)
.unwrap();
}78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}sourcepub fn max_conns(self, n: usize) -> Self
pub fn max_conns(self, n: usize) -> Self
Sets the maximum number of connections to handle at one time.
When the server is handling the maximum number of connections, it waits for a connection to drop before accepting new ones.
Each connection uses a file handle. Some processes run with a limit on the number of file handles. The OS kernel also has a limit for all processes combined.
Panics
Panics when n is zero.
Examples found in repository?
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/subscribe");
let event_sender_thread_permit = Permit::new();
let state = Arc::new(State::new());
let state_clone = state.clone();
std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.spawn_and_join(request_handler),
)
.unwrap();
}More examples
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}sourcepub fn receive_large_bodies(self, cache_dir: &Path) -> Self
pub fn receive_large_bodies(self, cache_dir: &Path) -> Self
Save large request bodies to this directory.
If you do not call this method, the server will refuse all
requests with bodies larger than small_body_len with 413 Payload Too Large.
It will also refuse all bodies with unknown length.
Example
use servlin::{HttpServerBuilder, Request, Response};
use servlin::reexport::{safina_executor, safina_timer};
use std::io::Read;
let cache_dir = temp_dir::TempDir::new().unwrap();
let handler = move |req: Request| {
if req.body.is_pending() {
return Response::get_body_and_reprocess(1024 * 1024);
}
let len = req.body.reader().unwrap().bytes().count();
Response::text(200, format!("body len={}", len))
};
safina_timer::start_timer_thread();
safina_executor::Executor::default().block_on(
HttpServerBuilder::new()
.receive_large_bodies(cache_dir.path())
.spawn_and_join(handler)
).unwrap();Examples found in repository?
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}sourcepub fn small_body_len(self, n: usize) -> Self
pub fn small_body_len(self, n: usize) -> Self
Automatically receive request bodies up to length n,
saving them in memory.
The default value is 64 KiB.
Reject larger requests with 413 Payload Too Large.
See receive_large_bodies.
You can estimate the server memory usage with:
small_body_len * max_conns.
Using the default settings: 64 KiB * 100 connections => 6.4 MiB.
Examples found in repository?
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}sourcepub fn permit(self, p: Permit) -> Self
pub fn permit(self, p: Permit) -> Self
Sets the permit used by the server.
Revoke the permit to make the server gracefully shut down.
Example
use servlin::{Response, HttpServerBuilder};
use servlin::reexport::{safina_executor, safina_timer};
use std::net::SocketAddr;
use permit::Permit;
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let permit = Permit::new();
let (addr, stopped_receiver) = executor.block_on(
HttpServerBuilder::new()
.permit(permit.new_sub())
.spawn(move |req| Response::text(200, "yo"))
).unwrap();
do_some_requests(addr).unwrap();
drop(permit); // Tell server to shut down.
stopped_receiver.recv(); // Wait for server to stop.sourcepub async fn spawn<F>(
self,
request_handler: F
) -> Result<(SocketAddr, Receiver<()>), Error>
pub async fn spawn<F>( self, request_handler: F ) -> Result<(SocketAddr, Receiver<()>), Error>
Spawns the server task.
Returns (addr, stopped_receiver).
The server is listening on addr.
After the server gracefully shuts down, it sends a message on stopped_receiver.
Errors
Returns an error when it fails to bind to the listen_addr.
sourcepub async fn spawn_and_join<F>(self, request_handler: F) -> Result<(), Error>
pub async fn spawn_and_join<F>(self, request_handler: F) -> Result<(), Error>
Spawns the server task and waits for it to shutdown gracefully.
Errors
Returns an error when it fails to bind to the listen_addr.
Examples found in repository?
More examples
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/subscribe");
let event_sender_thread_permit = Permit::new();
let state = Arc::new(State::new());
let state_clone = state.clone();
std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.spawn_and_join(request_handler),
)
.unwrap();
}78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub fn main() {
println!("Access the server at http://127.0.0.1:8000/upload");
let _guard = set_global_logger(
LogFileWriter::new_builder("log", 100 * 1024 * 1024)
.start_writer_thread()
.unwrap(),
)
.unwrap();
safina_timer::start_timer_thread();
let executor = safina_executor::Executor::default();
let cache_dir = TempDir::new().unwrap();
let state = Arc::new(State::new());
let request_handler =
move |req: Request| log_request_and_response(req, |req| handle_req(state, req)).unwrap();
executor
.block_on(
HttpServerBuilder::new()
.listen_addr(socket_addr_127_0_0_1(8000))
.max_conns(100)
.small_body_len(64 * 1024)
.receive_large_bodies(cache_dir.path())
.spawn_and_join(request_handler),
)
.unwrap();
}