Struct HttpServerBuilder

Source
pub struct HttpServerBuilder { /* private fields */ }
Expand description

Builds an HTTP server.

Implementations§

Source§

impl HttpServerBuilder

Source

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?
examples/minimal.rs (line 26)
21pub fn main() {
22    safina_timer::start_timer_thread();
23    let executor = safina_executor::Executor::default();
24    executor
25        .block_on(
26            HttpServerBuilder::new()
27                .listen_addr(socket_addr_127_0_0_1(8000))
28                .spawn_and_join(|_req: Request| Response::not_found_404()),
29        )
30        .unwrap();
31}
More examples
Hide additional examples
examples/http-put.rs (line 79)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
examples/events-sse.rs (line 91)
80pub fn main() {
81    println!("Access the server at http://127.0.0.1:8000/subscribe");
82    let event_sender_thread_permit = Permit::new();
83    let state = Arc::new(State::new());
84    let state_clone = state.clone();
85    std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
86    safina_timer::start_timer_thread();
87    let executor = safina_executor::Executor::default();
88    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
89    executor
90        .block_on(
91            HttpServerBuilder::new()
92                .listen_addr(socket_addr_127_0_0_1(8000))
93                .max_conns(100)
94                .spawn_and_join(request_handler),
95        )
96        .unwrap();
97}
Source

pub fn listen_addr(self, addr: SocketAddr) -> Self

Examples found in repository?
examples/minimal.rs (line 27)
21pub fn main() {
22    safina_timer::start_timer_thread();
23    let executor = safina_executor::Executor::default();
24    executor
25        .block_on(
26            HttpServerBuilder::new()
27                .listen_addr(socket_addr_127_0_0_1(8000))
28                .spawn_and_join(|_req: Request| Response::not_found_404()),
29        )
30        .unwrap();
31}
More examples
Hide additional examples
examples/http-put.rs (line 80)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
examples/events-sse.rs (line 92)
80pub fn main() {
81    println!("Access the server at http://127.0.0.1:8000/subscribe");
82    let event_sender_thread_permit = Permit::new();
83    let state = Arc::new(State::new());
84    let state_clone = state.clone();
85    std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
86    safina_timer::start_timer_thread();
87    let executor = safina_executor::Executor::default();
88    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
89    executor
90        .block_on(
91            HttpServerBuilder::new()
92                .listen_addr(socket_addr_127_0_0_1(8000))
93                .max_conns(100)
94                .spawn_and_join(request_handler),
95        )
96        .unwrap();
97}
Source

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?
examples/http-put.rs (line 81)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
More examples
Hide additional examples
examples/events-sse.rs (line 93)
80pub fn main() {
81    println!("Access the server at http://127.0.0.1:8000/subscribe");
82    let event_sender_thread_permit = Permit::new();
83    let state = Arc::new(State::new());
84    let state_clone = state.clone();
85    std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
86    safina_timer::start_timer_thread();
87    let executor = safina_executor::Executor::default();
88    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
89    executor
90        .block_on(
91            HttpServerBuilder::new()
92                .listen_addr(socket_addr_127_0_0_1(8000))
93                .max_conns(100)
94                .spawn_and_join(request_handler),
95        )
96        .unwrap();
97}
Source

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 std::io::Read;
use beatrice::{HttpServerBuilder, Request, Response};
use beatrice::reexport::{safina_executor, safina_timer};

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?
examples/http-put.rs (line 83)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
Source

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?
examples/http-put.rs (line 82)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
Source

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 std::net::SocketAddr;
use permit::Permit;
use beatrice::{Response, HttpServerBuilder};
use beatrice::reexport::{safina_executor, safina_timer};

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.
Source

pub async fn spawn<F>( self, request_handler: F, ) -> Result<(SocketAddr, Receiver<()>), Error>
where F: FnOnce(Request) -> Response + 'static + Clone + Send + Sync,

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.

Source

pub async fn spawn_and_join<F>(self, request_handler: F) -> Result<(), Error>
where F: FnOnce(Request) -> Response + 'static + Clone + Send + Sync,

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?
examples/minimal.rs (line 28)
21pub fn main() {
22    safina_timer::start_timer_thread();
23    let executor = safina_executor::Executor::default();
24    executor
25        .block_on(
26            HttpServerBuilder::new()
27                .listen_addr(socket_addr_127_0_0_1(8000))
28                .spawn_and_join(|_req: Request| Response::not_found_404()),
29        )
30        .unwrap();
31}
More examples
Hide additional examples
examples/http-put.rs (line 84)
70pub fn main() {
71    println!("Access the server at http://127.0.0.1:8000/upload");
72    safina_timer::start_timer_thread();
73    let executor = safina_executor::Executor::default();
74    let cache_dir = TempDir::new().unwrap();
75    let state = Arc::new(State::new());
76    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
77    executor
78        .block_on(
79            HttpServerBuilder::new()
80                .listen_addr(socket_addr_127_0_0_1(8000))
81                .max_conns(100)
82                .small_body_len(64 * 1024)
83                .receive_large_bodies(cache_dir.path())
84                .spawn_and_join(request_handler),
85        )
86        .unwrap();
87}
examples/events-sse.rs (line 94)
80pub fn main() {
81    println!("Access the server at http://127.0.0.1:8000/subscribe");
82    let event_sender_thread_permit = Permit::new();
83    let state = Arc::new(State::new());
84    let state_clone = state.clone();
85    std::thread::spawn(move || event_sender_thread(state_clone, event_sender_thread_permit));
86    safina_timer::start_timer_thread();
87    let executor = safina_executor::Executor::default();
88    let request_handler = move |req: Request| print_log_response(&req, handle_req(&state, &req));
89    executor
90        .block_on(
91            HttpServerBuilder::new()
92                .listen_addr(socket_addr_127_0_0_1(8000))
93                .max_conns(100)
94                .spawn_and_join(request_handler),
95        )
96        .unwrap();
97}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,