Skip to main content

Server

Struct Server 

Source
pub struct Server<Addr: Address, A = DefaultAcceptor> { /* private fields */ }
Expand description

HTTP server.

Implementations§

Source§

impl<A: Address> Server<A>

Source

pub fn bind(addr: A) -> Self

Create a server that will bind to provided address.

Examples found in repository?
examples/timeouts.rs (line 24)
19async fn main() {
20    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
21
22    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
23
24    let mut server = Server::bind(addr).first_request_timeout(Duration::from_secs(10));
25
26    let mut http1 = server.http_builder().http1();
27    http1.header_read_timeout(Duration::from_secs(10));
28
29    let mut http2 = server.http_builder().http2();
30    http2.keep_alive_interval(Duration::from_secs(30));
31    http2.keep_alive_timeout(Duration::from_secs(10));
32
33    println!("listening on {addr}");
34    server.serve(app.into_make_service()).await.unwrap();
35}
Source

pub fn from_listener(listener: A::Listener) -> Self

Create a server from an existing AddrListener.

Source§

impl<A: Address, Acc> Server<A, Acc>

Source

pub fn acceptor<Acceptor>(self, acceptor: Acceptor) -> Server<A, Acceptor>

Overwrite acceptor.

Examples found in repository?
examples/async_sni.rs (line 41)
30async fn main() {
31    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
32
33    let acceptor = AsyncSniAcceptor::new(CertificateStore::example());
34    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
35
36    println!("listening on {addr}");
37    println!("try: curl -k --resolve localhost:3000:127.0.0.1 https://localhost:3000/");
38    println!("try: curl -k --resolve other.test:3000:127.0.0.1 https://other.test:3000/");
39
40    axum_server::bind(addr)
41        .acceptor(acceptor)
42        .serve(app.into_make_service())
43        .await
44        .unwrap();
45}
More examples
Hide additional examples
examples/acme.rs (line 68)
24async fn main() {
25    let domains = env::var("ACME_DOMAINS")
26        .expect("set ACME_DOMAINS to a comma-separated list of domains")
27        .split(',')
28        .map(str::to_owned)
29        .collect::<Vec<_>>();
30
31    let cache = env::var("ACME_CACHE").unwrap_or_else(|_| "./acme-cache".to_owned());
32    let port = env::var("ACME_PORT")
33        .ok()
34        .and_then(|port| port.parse().ok())
35        .unwrap_or(443);
36    let production = env::var("ACME_PRODUCTION").is_ok_and(|value| value == "1");
37
38    let mut config = AcmeConfig::new(domains)
39        .cache(DirCache::new(cache))
40        .directory_lets_encrypt(production);
41
42    if let Ok(contact) = env::var("ACME_CONTACT") {
43        config = config.contact([format!("mailto:{contact}")]);
44    }
45
46    let mut state = config.state();
47    let acceptor = Acceptor::new(&state);
48
49    // Polling the state is what acquires and renews the certificates.
50    tokio::spawn(async move {
51        while let Some(event) = state.next().await {
52            match event {
53                Ok(event) => println!("acme: {event:?}"),
54                Err(error) => eprintln!("acme error: {error:?}"),
55            }
56        }
57    });
58
59    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
60    let addr = SocketAddr::from(([0, 0, 0, 0], port));
61
62    println!("listening on https://{addr}");
63    if !production {
64        println!("using the Let's Encrypt staging directory");
65    }
66
67    axum_server::bind(addr)
68        .acceptor(acceptor)
69        .serve(app.into_make_service())
70        .await
71        .unwrap();
72}
Source

pub fn map<Acceptor, F>(self, acceptor: F) -> Server<A, Acceptor>
where F: FnOnce(Acc) -> Acceptor,

Map acceptor.

Source

pub fn get_ref(&self) -> &Acc

Returns a reference to the acceptor.

Source

pub fn get_mut(&mut self) -> &mut Acc

Returns a mutable reference to the acceptor.

Source

pub fn http_builder(&mut self) -> &mut Builder<TokioExecutor>

Returns a mutable reference to the Http builder.

Examples found in repository?
examples/timeouts.rs (line 26)
19async fn main() {
20    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
21
22    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
23
24    let mut server = Server::bind(addr).first_request_timeout(Duration::from_secs(10));
25
26    let mut http1 = server.http_builder().http1();
27    http1.header_read_timeout(Duration::from_secs(10));
28
29    let mut http2 = server.http_builder().http2();
30    http2.keep_alive_interval(Duration::from_secs(30));
31    http2.keep_alive_timeout(Duration::from_secs(10));
32
33    println!("listening on {addr}");
34    server.serve(app.into_make_service()).await.unwrap();
35}
Source

pub fn http1_only(self) -> Self

Only accepts HTTP/1.

Note that HTTP/1 protocol upgrades (for example WebSockets) are not supported when this is used; the default protocol-detecting mode does support them.

Source

pub fn http2_only(self) -> Self

Only accepts HTTP/2.

Source

pub fn handle(self, handle: Handle<A>) -> Self

Provide a handle for additional utilities.

To share shutdown and connection counting between servers listening on different address types, build each server’s handle from one Control with Handle::with_control.

Examples found in repository?
examples/shutdown.rs (line 24)
13async fn main() {
14    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
15
16    let handle = Handle::new();
17
18    // Spawn a task to shutdown server.
19    tokio::spawn(shutdown(handle.clone()));
20
21    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
22    println!("listening on {}", addr);
23    axum_server::bind(addr)
24        .handle(handle)
25        .serve(app.into_make_service())
26        .await
27        .unwrap();
28
29    println!("server is shut down");
30}
More examples
Hide additional examples
examples/graceful_shutdown.rs (line 27)
16async fn main() {
17    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
18
19    let handle = Handle::new();
20
21    // Spawn a task to gracefully shutdown server.
22    tokio::spawn(graceful_shutdown(handle.clone()));
23
24    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
25    println!("listening on {}", addr);
26    axum_server::bind(addr)
27        .handle(handle)
28        .serve(app.into_make_service())
29        .await
30        .unwrap();
31
32    println!("server is shut down");
33}
examples/multiple_listeners.rs (line 16)
7async fn main() -> io::Result<()> {
8    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
9
10    // One control handle drains every listener below.
11    let control = Control::new();
12    let mut servers = JoinSet::new();
13
14    let tcp_handle = Handle::<SocketAddr>::with_control(control.clone());
15    let tcp =
16        axum_server::bind(SocketAddr::from(([127, 0, 0, 1], 3000))).handle(tcp_handle.clone());
17    let tcp_service = app.clone().into_make_service();
18
19    servers.spawn(async move { tcp.serve(tcp_service).await });
20
21    #[cfg(unix)]
22    let unix_handle = {
23        use std::os::unix::net::SocketAddr;
24
25        let path = std::env::temp_dir().join("axum-server-multiple-listeners.sock");
26        let _ = std::fs::remove_file(&path);
27
28        let handle = Handle::with_control(control.clone());
29        let unix = axum_server::bind(SocketAddr::from_pathname(path)?).handle(handle.clone());
30        let service = app.clone().into_make_service();
31
32        servers.spawn(async move { unix.serve(service).await });
33
34        handle
35    };
36
37    println!("tcp: http://{}/", tcp_handle.listening().await.unwrap());
38    #[cfg(unix)]
39    println!(
40        "unix: {:?}",
41        unix_handle
42            .listening()
43            .await
44            .unwrap()
45            .as_pathname()
46            .unwrap()
47    );
48
49    let shutdown = control.clone();
50    tokio::spawn(async move {
51        let _ = tokio::signal::ctrl_c().await;
52        shutdown.graceful_shutdown(Some(Duration::from_secs(10)));
53    });
54
55    // A failing listener stops the others instead of leaving them running.
56    while let Some(result) = servers.join_next().await {
57        match result {
58            Ok(Ok(())) => {}
59            Ok(Err(error)) => {
60                eprintln!("server error: {error}");
61                control.shutdown();
62            }
63            Err(error) => {
64                eprintln!("server task failed: {error}");
65                control.shutdown();
66            }
67        }
68    }
69
70    #[cfg(unix)]
71    let _ = std::fs::remove_file(std::env::temp_dir().join("axum-server-multiple-listeners.sock"));
72
73    Ok(())
74}
Source

pub fn first_request_timeout(self, timeout: impl Into<Option<Duration>>) -> Self

Set a timeout for the first request on a connection.

If the client does not send a complete first request within this duration, the connection is closed. This bounds the time a newly accepted connection can occupy resources before the HTTP protocol is determined, which is otherwise not covered by http_builder timeouts.

The timeout starts after the connection acceptor finishes. For a TLS server this means the TLS handshake is bounded by the acceptor’s own handshake timeout instead.

None disables the timeout. The default is None.

Examples found in repository?
examples/timeouts.rs (line 24)
19async fn main() {
20    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
21
22    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
23
24    let mut server = Server::bind(addr).first_request_timeout(Duration::from_secs(10));
25
26    let mut http1 = server.http_builder().http1();
27    http1.header_read_timeout(Duration::from_secs(10));
28
29    let mut http2 = server.http_builder().http2();
30    http2.keep_alive_interval(Duration::from_secs(30));
31    http2.keep_alive_timeout(Duration::from_secs(10));
32
33    println!("listening on {addr}");
34    server.serve(app.into_make_service()).await.unwrap();
35}
Source

pub fn accept_error_handler<F>(self, handler: F) -> Self
where F: Fn(Option<&A>, &Error) + Send + Sync + 'static,

Set a handler called when accepting a connection fails.

The handler receives the remote address when it is known and the error that occurred. Accept errors do not stop the server; it backs off and keeps accepting.

The handler is called from the accept loop, so keep it cheap. Use it for logging or metrics rather than blocking work.

Source

pub async fn serve<M>(self, make_service: M) -> Result<()>
where M: MakeService<A, Request<Incoming>>, A: Send + 'static, A::Stream: Send, Acc: Accept<A::Stream, M::Service> + Clone + Send + Sync + 'static, Acc::Stream: AsyncRead + AsyncWrite + Unpin + Send, Acc::Service: SendService<Request<Incoming>> + Send, Acc::Future: Send,

Serve provided MakeService.

To create MakeService easily, Shared from tower can be used.

§Errors

An error will be returned when:

  • Binding to an address fails.
  • make_service returns an error when poll_ready is called. This never happens on axum make services.
Examples found in repository?
examples/multiple_addresses.rs (line 22)
18async fn start_server(addr: SocketAddr) {
19    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
20
21    axum_server::bind(addr)
22        .serve(app.into_make_service())
23        .await
24        .unwrap();
25}
More examples
Hide additional examples
examples/remote_address.rs (line 16)
9async fn main() {
10    let app = Router::new()
11        .route("/", get(handler))
12        .into_make_service_with_connect_info::<SocketAddr>();
13
14    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
15
16    axum_server::bind(addr).serve(app).await.unwrap();
17}
examples/http_and_https.rs (line 25)
19async fn http_server() {
20    let app = Router::new().route("/", get(http_handler));
21
22    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
23    println!("http listening on {}", addr);
24    axum_server::bind(addr)
25        .serve(app.into_make_service())
26        .await
27        .unwrap();
28}
29
30async fn http_handler(uri: Uri) -> Redirect {
31    let uri = format!("https://127.0.0.1:3443{}", uri.path());
32
33    Redirect::temporary(&uri)
34}
35
36async fn https_server() {
37    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
38
39    let config = RustlsConfig::from_pem_file(
40        "examples/self-signed-certs/cert.pem",
41        "examples/self-signed-certs/key.pem",
42    )
43    .await
44    .unwrap();
45
46    let addr = SocketAddr::from(([127, 0, 0, 1], 3443));
47    println!("https listening on {}", addr);
48    axum_server::bind_rustls(addr, config)
49        .serve(app.into_make_service())
50        .await
51        .unwrap();
52}
examples/hello_world.rs (line 15)
9async fn main() {
10    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
11
12    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
13    println!("listening on {}", addr);
14    axum_server::bind(addr)
15        .serve(app.into_make_service())
16        .await
17        .unwrap();
18}
examples/hello_world_unix.rs (line 15)
9async fn main() {
10    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
11
12    let addr = SocketAddr::from_pathname("/tmp/axum-server.sock").unwrap();
13    println!("listening on {}", addr.as_pathname().unwrap().display());
14    axum_server::bind(addr)
15        .serve(app.into_make_service())
16        .await
17        .unwrap();
18}
examples/from_std_listener.rs (line 17)
9async fn main() {
10    let app = Router::new().route("/", get(|| async { "Hello, world!" }));
11
12    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
13    let listener = TcpListener::bind(addr).unwrap();
14    println!("listening on {}", addr);
15    axum_server::from_tcp(listener)
16        .unwrap()
17        .serve(app.into_make_service())
18        .await
19        .unwrap();
20}

Trait Implementations§

Source§

impl<A: Address, B> Debug for Server<A, B>
where Listener<A>: Debug, Handle<A>: Debug, B: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Addr, A = DefaultAcceptor> !RefUnwindSafe for Server<Addr, A>

§

impl<Addr, A = DefaultAcceptor> !UnwindSafe for Server<Addr, A>

§

impl<Addr, A> Forget for Server<Addr, A>

§

impl<Addr, A> Freeze for Server<Addr, A>
where A: Freeze, Listener<Addr>: Freeze, Handle<Addr>: Freeze, Option<Arc<dyn Fn(Option<&Addr>, &Error) + Sync + Send>>: Freeze,

§

impl<Addr, A> Send for Server<Addr, A>
where A: Send, Listener<Addr>: Send, Handle<Addr>: Send, Option<Arc<dyn Fn(Option<&Addr>, &Error) + Sync + Send>>: Send,

§

impl<Addr, A> Sync for Server<Addr, A>
where A: Sync, Listener<Addr>: Sync, Handle<Addr>: Sync, Option<Arc<dyn Fn(Option<&Addr>, &Error) + Sync + Send>>: Sync,

§

impl<Addr, A> Unpin for Server<Addr, A>
where A: Unpin, Listener<Addr>: Unpin, Handle<Addr>: Unpin, Option<Arc<dyn Fn(Option<&Addr>, &Error) + Sync + Send>>: Unpin,

§

impl<Addr, A> UnsafeUnpin for Server<Addr, A>
where A: UnsafeUnpin, Listener<Addr>: UnsafeUnpin, Handle<Addr>: UnsafeUnpin, Option<Arc<dyn Fn(Option<&Addr>, &Error) + Sync + Send>>: UnsafeUnpin,

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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more