axum-server is a hyper server implementation designed to be used with axum framework.

Overview

License Docs - Master Docs - Stable

axum-server

axum-server is a hyper server implementation designed to be used with axum framework.

Features

  • Conveniently bind to any number of addresses.
  • Tls support through rustls. Only pem format is supported.
  • Reload tls while server is running.
  • Access to client ip address from services/handlers.
  • Record incoming and outgoing bytes for each connection.
  • Services created by axum can directly be served.
  • Although designed to be used with axum, any Service that implements Clone can be served.

Usage example

axum "Hello, World!" example can be run like:

use axum::{
    handler::get,
    Router,
};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello, World!" }));

    axum_server::bind("127.0.0.1:3000")
        .serve(app)
        .await
        .unwrap();
}

Safety

This crate uses #![forbid(unsafe_code)] to ensure everything is implemented in 100% safe Rust.

License

This project is licensed under the MIT license.

Comments
  • Hybrid server with axum+tonic

    Hybrid server with axum+tonic

    I am trying to build a hybrid HTTP + gRPC server using Axum and Tonic following this example. I am struggling a bit however on how to combine this with axum-server to have both over TLS:

    let app = /* axum app */;
    let grpc_service = tonic::transport::Server::builder().add_service(/* some gRPC service */).into_service();
    let hybrid_make_service = hybrid(app.into_make_service(), grpc_service);
    
    // This works fine
    axum::Server::bind(&sc.bind_address).serve(hybrid_make_service).await?;
    
    // This I can't get right...
    axum_server::bind_rustls(sc.bind_address.to_string())
    				.private_key_file(tls_key_path)
    				.certificate_file(tls_cert_path)
    				.serve(hybrid_make_service)
    				.await?;
    

    The issue seems to be that axum_server requires a 'Service' whereas the regular 'bind' accepts some sort of 'IntoService' (and the hybrid function, as well as grpc_service, create this). Any ideas?

    documentation 
    opened by pixelspark 10
  • Obtaining actual bound listener port?

    Obtaining actual bound listener port?

    When the SockAddr bind port is specified as 0, the kernel picks a random port to listen on. How does one gain access to this bound listener port? axum allows access to https://docs.rs/hyper/0.14.18/hyper/server/struct.Server.html#method.local_addr, how can one obtain the equivalent information using axum-server?

    opened by josb 6
  • HTTP/2 with rustls-acme

    HTTP/2 with rustls-acme

    Hello,

    I use rustls-acme to create automatically Let's Encrypt certificates like in https://github.com/FlorianUekermann/rustls-acme/blob/main/examples/low_level_axum.rs . It works very well, but the server seems not to respond with HTTP/2, even if the http2 feature is enabled in axum.

    How can I enable HTTP/2 ?

    Thanks and best regards.

    documentation 
    opened by nicolaspernoud 5
  • error: no rules expected the token `;`

    error: no rules expected the token `;`

    I seem to be having trouble incorporating the example code into a toy project I am playing with to learn a bit of rust.

    Not sure what he cause is, but I'm on 1.64 on fedora if that makes much of a difference

       Compiling axum-server v0.4.2
    error: no rules expected the token `;`
      --> /home/fejfighter/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-server-0.4.2/src/handle.rs:94:23
       |
    94 |                 biased;
       |                       ^ no rules expected this token in macro call
    
    error: no rules expected the token `;`
       --> /home/fejfighter/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-server-0.4.2/src/server.rs:175:27
        |
    175 |                     biased;
        |                           ^ no rules expected this token in macro call
    
    error: no rules expected the token `;`
       --> /home/fejfighter/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-server-0.4.2/src/server.rs:204:35
        |
    204 | ...                   biased;
        |                             ^ no rules expected this token in macro call
    
    error: no rules expected the token `;`
       --> /home/fejfighter/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-server-0.4.2/src/server.rs:214:19
        |
    214 |             biased;
        |                   ^ no rules expected this token in macro call
    
    error: could not compile `axum-server` due to 4 previous errors
    
    opened by fejfighter 4
  • Split ServerBuilder and Server structs.

    Split ServerBuilder and Server structs.

    This takes a slightly different approach to what you suggested in #33, just wanted to get some quick feedback whether you think this would also be a good solution.

    The main idea is to split up the builder from the actual server struct and bundle the server future together with the actually bound address.

    opened by sebpuetz 4
  • axum_server doesn't work with unreleased version of axum (0.3.0)

    axum_server doesn't work with unreleased version of axum (0.3.0)

    Lately Axum has modified the internal implementation of Router and they have started boxing the routers by default (https://github.com/tokio-rs/axum). Unfortunately these new changes don't work with axum_server. I get following compilation error:

    error[E0277]: `(dyn axum::clone_box_service::CloneService<axum::http::Request<axum::body::Body>, Response = axum::http::Response<http_body::combinators::box_body::UnsyncBoxBody<bytes::Bytes, axum::Error>>, Error = Infallible, Future = Pin<Box<(dyn futures_util::Future<Output = Result<axum::http::Response<http_body::combinators::box_body::UnsyncBoxBody<bytes::Bytes, axum::Error>>, Infallible>> + std::marker::Send + 'static)>>> + std::marker::Send + 'static)` cannot be shared between threads safely
    
    opened by pbspbsingh 4
  • Does this guard against TCP connection leaks during SSL handshake?

    Does this guard against TCP connection leaks during SSL handshake?

    I recently decided to port my application to the axum framework, and intend for my Rust binary to do its own SSL. This crate seems like the best way to achieve that (especially since it supports hot-swapping certificates :tada:). However, one of the issues I had with a previous web framework was severe, persistent TCP connection leaks, due in part to a lack of a timeout on accepting SSL connections (and also during http2 upgrade, but that's outside the scope of this crate). When I took a look at the source code, I couldn't help but notice that no timeouts or sleeps were incorporated into the relevant Futures. This leads me to believe that, were I to deploy my application in production, I would see TCP connection counts steadily climb as real clients have a habit of silently hanging up their connection at the worst time.

    So my questions are:

    1. Does this (or hyper, or axum) impose any timeout for SSL handshake? (or otherwise prevent this form of TCP connection leakage?)
    2. If not, is there a workaround (such as implementing a custom acceptor)?
    3. Would you prefer if I write a short test case to demonstrate an issue or lack there of?
    opened by finnbear 3
  • How to support https and http dual protocol with rewrite-minimal branch

    How to support https and http dual protocol with rewrite-minimal branch

    hi, Eray, i've tested your recent posted rewrite-minimal redesign version, it works! but i noticed one problem: there is no way to make a single server to provide https and http dual protocol like version 0.2.5. This is a must-have feature, please please conside it.

    opened by c5soft 3
  • Document how to use a `Service` factory for `Server::serve()`

    Document how to use a `Service` factory for `Server::serve()`

    I would like to wrap a user supplied app, like a Router, for that purpose I would like to use ServiceBuilder.

    The issue is that Server::serve() needs a service factory, like what can be produced with Router::into_make_service(), which isn't available for ServiceBuilder.

    The solution I found is wrapping it in Shared. I believe some documentation in axum-server would help.

    See https://github.com/tokio-rs/axum/issues/1203 for the original problem.

    opened by daxpedda 2
  • Graceful shutdown doesn't include upgraded connections

    Graceful shutdown doesn't include upgraded connections

    Hi,

    When using Axum with WebSockets, I noticed having an open WebSocket doesn't stop the server from shutting down gracefully. Here's a demo repository.

    My expectation was that the demo would remain running for 30 seconds, printing "beep" every second until the graceful shutdown timeout is reached.

    I'm not terribly familiar with Hyper so I don't immediately see a fix, so I figured I'd start with an issue. I'm happy to work on a fix, however.

    opened by jeremycline 2
  • from_pem_file() rejects valid EC keys

    from_pem_file() rejects valid EC keys

    from_pem_file() calls eventually to config_from_pem() which restricts the keys to be of type Some(Item::RSAKey(key)) or Some(Item::PKCS8Key(key)) and this rejects a lot of EC keys. One either needs to convert it from SEC1 to PKCS8 or directly encode into DER and load the files by hand to call from_der() instead.

    Adding proper support for EC keys should be as simple as adding Some(Item::ECKey(key)) to the match clause of config_from_pem(). I'd be happy to open a pull request for it.

    opened by Echaleon 2
  • Listen on multiple sockets

    Listen on multiple sockets

    I really do like the easy of working with axum and axum-server. It is straightforward to set up TLS and reload it, which is awesome when used with certificates that need to renewed often.

    I would be genuinely interested in binding a server to multiple sockets of different types. For example, to accept an arbitrary list of TCP and unix domain sockets via systemd socket activation:

    	let tls_config = RustlsConfig::from_pem_file(
    		"examples/self-signed-certs/cert.pem",
    		"examples/self-signed-certs/key.pem",
    	)
    	.await?;
    
    	let server = axum_server::new();
    
    	let mut lfd = ListenFd::from_env();
    	if lfd.len() > 0 {
    		for idx in 0..lfd.len() {
    			if let Ok(Some(lst)) = lfd.take_tcp_listener(idx) {
    				server = server.from_tcp_rustls(lst, tls_config);
    			} else if let Ok(Some(lst)) = lfd.take_unix_listener(idx) {
    				server = server.from_uds(lst);
    			} else {
    				warn!("Unsupported socket type at index {:?}", idx)
    			}
    		}
    	} else {
    		server = server.bind("[::]:3000".parse()?)
    	}
    
    	let app = Router::new().route("/", get(|| async { "Hello World" }));
    	server.serve(app.into_make_service()).await?;
    

    Having the same app listening on multiple sockets greatly improves usability and integration with many systems, such as systemd. Unix domain sockets are often used to provide a service to other local services, such as reverse proxies or load balancers. A second TCP listener is often spawned e.g. for debugging or monitoring purposes.

    Does this feature sound reasonable for axum-server?

    opened by jgraichen 0
  • HTTP and HTTPS on the same port

    HTTP and HTTPS on the same port

    I wrote an Acceptor that allows handling of HTTP and HTTPS on the same port. The implementation is fairly minimal and simple. Is it in scope for axum-server to add something like this? Happy to start a PR of course.

    My use-case is hosting a HTTPS server on a custom port, unlike the example, there is only one port. So connecting with HTTP to that server errors out. The idea is if I accept both protocols, I can design a middleware that handles the redirect.

    opened by daxpedda 7
  • `util` module for higher level features

    `util` module for higher level features

    An util module with optional util feature can be created to provide higher level features.

    Some possible high level features:

    • Recording bytes for each connection. This can be useful to log client data usage.
    • Binding to multiple addresses on a single struct.
    • Http and https server on a single struct.
    enhancement 
    opened by programatik29 0
  • Give more control on connection tasks

    Give more control on connection tasks

    Currently there is no way to shut a connection down except signaling a global shutdown.

    Having this ability can be useful to detect slow clients and prevent some attacks.

    enhancement 
    opened by programatik29 4
Releases(v0.4.3)
  • v0.4.3(Nov 3, 2022)

  • v0.4.2(Aug 5, 2022)

    • added: Added Server::from_tcp, axum_server::from_tcp and axum_server::from_tcp_rustls methods to create Server from std::net::TcpListener.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Jul 29, 2022)

  • v0.4.0(Apr 18, 2022)

    • Added TLS handshake timeout(10 seconds).
    • In RustlsConfig: from_pem and from_pem_file methods now accept EC keys.
    • added: Added AddrIncomingConfig to allow configuration of hyper::server::conn::AddrIncoming.
    • added: Added HttpConfig::http1_header_read_timeout.
    • breaking: Changed Handle::listening return type to Option<SocketAddr>. If binding fails, Option::None will be returned.
    Source code(tar.gz)
    Source code(zip)
  • v0.3.2(Nov 17, 2021)

  • v0.3.1(Nov 10, 2021)

  • v0.3.0(Nov 10, 2021)

    • Total rewrite of source code.
    • Major api changes:
      • breaking: Removed bind_rustls, certificate, certificate_file, loader, new, private_key, private_key_file, serve_and_record, tls_config methods from Server.
      • breaking: Removed tls module.
      • breaking: Removed record module and feature.
      • breaking: Removed Handle::listening_addrs method.
      • breaking: Server::bind method doesn't take self anymore and creates an Server.
      • breaking: bind method now takes a SocketAddr.
      • breaking: bind_rustls method now takes a SocketAddr and an tls_rustls::RustlsConfig.
      • breaking: Server::serve method now takes a MakeService.
      • breaking: Handle::listening method now returns SocketAddr.
      • added: Added Handle::connection_count that can be used to get alive connection count.
      • added: Added service module.
      • added: Added service::MakeServiceRef and service::SendService traits aliases for convenience.
      • added: Added accept module.
      • added: Added accept::Accept trait that can be implemented to modify io stream and service.
      • added: Added accept::DefaultAcceptor struct that implements accept::Accept to be used as a default 'Accept' for 'Server'.
      • added: Added Server::acceptor method that can be used to provide a custom accept::Accept.
      • added: Added tls_rustls module.
      • added: Added tls_rustls::RustlsAcceptor that can be used with Server::acceptor to make a tls Server.
      • added: Added tls_rustls::RustlsConfig to create rustls utilities and to provide reload functionality.
      • added: Added tls_rustls::bind_rustls which is same as bind_rustls function.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.5(Oct 5, 2021)

  • v0.2.4(Sep 17, 2021)

  • v0.2.3(Sep 13, 2021)

  • v0.2.2(Sep 6, 2021)

  • v0.2.1(Aug 30, 2021)

  • v0.2.0(Aug 29, 2021)

  • v0.1.2(Aug 24, 2021)

  • v0.1.0(Aug 23, 2021)

Owner
null
TCP is so widely used, however QUIC may have a better performance.

TCP is so widely used, however QUIC may have a better performance. For softwares which use protocols built on TCP, this program helps them take FULL advantage of QUIC.

zephyr 15 Jun 10, 2022
Rust utility crate for parsing, encoding and generating x25519 keys used by WireGuard

WireGuard Keys This is a utility crate for parsing, encoding and generating x25519 keys that are used by WireGuard. It exports custom types that can b

Fractal Networks 3 Aug 9, 2022
Rust crate for configurable parallel web crawling, designed to crawl for content

url-crawler A configurable parallel web crawler, designed to crawl a website for content. Changelog Docs.rs Example extern crate url_crawler; use std:

Pop!_OS 56 Aug 22, 2021
📡 Rust mDNS library designed with user interfaces in mind

?? Searchlight Searchlight is an mDNS server & client library designed to be simple, lightweight and easy to use, even if you just have basic knowledg

William 5 Jan 8, 2023
Rust implementation of PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols

Rust PRECIS Framework libray PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols as descr

Santiago Carot-Nemesio 1 Oct 20, 2022
A working demo of RustDesk server implementation

A working demo of RustDesk server implementation This is a super simple working demo implementation with only one relay connection allowed, without NA

RustDesk 461 Jan 1, 2023
A high performence Socks5 proxy server with bind/reverse support implementation by Rust.

rsocx A high performence Socks5 proxy server with bind/reverse support implementation by Rust Features Async-std No unsafe code Single executable Linu

b23r0 259 Jan 6, 2023
Jex Compiler Server - Server that runs Jex code

Server that compiles and runs Jex code.

furetur 3 Nov 18, 2021
Dav-server-rs - Rust WebDAV server library. A fork of the webdav-handler crate.

dav-server-rs A fork of the webdav-handler-rs project. Generic async HTTP/Webdav handler Webdav (RFC4918) is defined as HTTP (GET/HEAD/PUT/DELETE) plu

messense 30 Dec 29, 2022
A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems.

x-server-stats A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems. x-server(in x-serv

Pratyaksh 11 Oct 17, 2022
DNS Server written in Rust for fun, see https://dev.to/xfbs/writing-a-dns-server-in-rust-1gpn

DNS Fun Ever wondered how you can write a DNS server in Rust? No? Well, too bad, I'm telling you anyways. But don't worry, this is going to be a fun o

Patrick Elsen 26 Jan 13, 2023
QUIC proxy that allows to use QUIC to connect to an SSH server without needing to patch the client or the server.

quicssh-rs ?? quicssh-rs is a QUIC proxy that allows to use QUIC to connect to an SSH server without needing to patch the client or the server. quicss

Jun Ouyang 18 May 5, 2023
Actor framework for Rust.

Actix Actor framework for Rust Documentation User Guide API Documentation API Documentation (master branch) Features Async and sync actors Actor commu

Actix 7.6k Jan 7, 2023
rpcx microservice framework in Rust

rpcx-rs Rust library for rpcx rpc/microservice framework. Use the simplest style to explore Rust function as cross-platform rpc services. If you can w

smallnest 105 Dec 19, 2022
A simple message based networking library for the bevy framework

Spicy Networking for Bevy bevy_spicy_networking is a solution to the "How do I connect multiple clients to a single server" problem in your bevy games

Cabbit Studios 67 Jan 1, 2023
Implementing Bendersnatch curve using Arkwork's framework in Rust.

This is a reference implementation of Bendersnatch curve using Arkwork's framework in Rust. The spec of the curve is available here. There was also a Python reference implementation here.

zhenfei 8 Jun 18, 2022
Fullstack development framework for UTXO-based dapps on Nervos Network

Trampoline-rs The framework for building powerful dApps on the number one UTXO chain, Nervos Network CKB. This is an early-stage, currently very incom

TannrA 2 Mar 25, 2022
A versatile and efficient proxy framework with nice features suitable for various use cases.

A versatile and efficient proxy framework with nice features suitable for various use cases.

null 1.7k Jan 9, 2023
Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem

Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem. With Astar Network and

Astar Network (Plasm) 43 Dec 14, 2022