axum_server_dual_protocol/
lib.rs

1//! # Description
2//!
3//! Provides utilities to host a [`axum-server`](axum_server) server that
4//! accepts the HTTP and HTTPS protocol on the same port. See
5//! [`bind_dual_protocol()`].
6//!
7//! A common use case for this is if a HTTPS server is hosted on a
8//! non-traditional port, having no corresponding HTTP port. This can be an
9//! issue for clients who try to connect over HTTP and get a connection reset
10//! error. See [`ServerExt::set_upgrade()`].
11//!
12//! # Usage
13//!
14//! The simplest way to start is to use [`bind_dual_protocol()`]:
15//! ```no_run
16//! # use axum::{routing, Router};
17//! # use axum_server::tls_rustls::RustlsConfig;
18//! # use axum_server_dual_protocol::Protocol;
19//! # use http::Extensions;
20//! #
21//! # #[tokio::main]
22//! # async fn main() -> anyhow::Result<()> {
23//! let app = Router::new().route(
24//! 	"/",
25//! 	routing::get(|extensions: Extensions| async move {
26//! 		match extensions.get::<Protocol>().unwrap() {
27//! 			Protocol::Tls => "Hello, secure World!",
28//! 			Protocol::Plain => "Hello, insecure World!",
29//! 		}
30//! 	}),
31//! );
32//!
33//! # let address = std::net::SocketAddr::from(([127, 0, 0, 1], 0));
34//! # let certificate = rcgen::generate_simple_self_signed([])?;
35//! # let private_key = certificate.key_pair.serialize_der();
36//! # let certificate = vec![certificate.cert.der().to_vec()];
37//! #
38//! // User-supplied certificate and private key.
39//! let config = RustlsConfig::from_der(certificate, private_key).await?;
40//!
41//! axum_server_dual_protocol::bind_dual_protocol(address, config)
42//! 	.serve(app.into_make_service())
43//! 	.await?;
44//! #
45//! # Ok(())
46//! # }
47//! ```
48//!
49//! We now have a server accepting both HTTP and HTTPS requests! Now we can
50//! automatically upgrade incoming HTTP requests to HTTPS using
51//! [`ServerExt::set_upgrade()`] like this:
52//! ```no_run
53//! # use axum::{routing, Router};
54//! # use axum_server::tls_rustls::RustlsConfig;
55//! use axum_server_dual_protocol::ServerExt;
56//!
57//! # #[tokio::main]
58//! # async fn main() -> anyhow::Result<()> {
59//! # let app = Router::new();
60//! # let address = std::net::SocketAddr::from(([127, 0, 0, 1], 0));
61//! # let certificate = rcgen::generate_simple_self_signed([])?;
62//! # let private_key = certificate.key_pair.serialize_der();
63//! # let certificate = vec![certificate.cert.der().to_vec()];
64//! # let config = RustlsConfig::from_der(certificate, private_key).await?;
65//! #
66//! axum_server_dual_protocol::bind_dual_protocol(address, config)
67//! 	.set_upgrade(true)
68//! 	.serve(app.into_make_service())
69//! 	.await?;
70//! #
71//! # Ok(())
72//! # }
73//! ```
74//!
75//! Alternatively [`UpgradeHttpLayer`] can be used:
76//! ```
77//! # use axum::{routing, Router};
78//! # use axum_server_dual_protocol::UpgradeHttpLayer;
79//! let app = Router::new()
80//! 	.route("/", routing::get(|| async { "Hello, world!" }))
81//! 	.layer(UpgradeHttpLayer);
82//! # // To help with type inference.
83//! # axum_server::bind(std::net::SocketAddr::from(([127, 0, 0, 1], 0)))
84//! # 	.serve(app.into_make_service());
85//! ```
86//!
87//! # Features
88//!
89//! ## `default`
90//!
91//! By default the [`aws-lc-rs`] [`CryptoProvider`] is enabled.
92//!
93//! # Conditional Configurations
94//!
95//! ## `docsrs`
96//!
97//! This requires Rust nightly and enhances the documentation. It must only be
98//! used with `RUSTDOCFLAGS`, not with `RUSTFLAGS`.
99//!
100//! # MSRV
101//!
102//! As this library heavily relies on [`axum-server`](axum_server), [`axum`],
103//! [`tower`] and [`hyper`] the MSRV depends on theirs. At the point of time
104//! this was written the highest MSRV was [`axum`] with 1.66.
105//!
106//! # Changelog
107//!
108//! See the [CHANGELOG] file for details.
109//!
110//! # License
111//!
112//! Licensed under either of
113//!
114//! - Apache License, Version 2.0 ([LICENSE-APACHE] or <http://www.apache.org/licenses/LICENSE-2.0>)
115//! - MIT license ([LICENSE-MIT] or <http://opensource.org/licenses/MIT>)
116//!
117//! at your option.
118//!
119//! ## Contribution
120//!
121//! Unless you explicitly state otherwise, any contribution intentionally
122//! submitted for inclusion in the work by you, as defined in the Apache-2.0
123//! license, shall be dual licensed as above, without any additional terms or
124//! conditions.
125//!
126//! [CHANGELOG]: https://github.com/daxpedda/axum-server-dual-protocol/blob/v0.7.0/CHANGELOG.md
127//! [LICENSE-MIT]: https://github.com/daxpedda/axum-server-dual-protocol/blob/v0.7.0/LICENSE-MIT
128//! [LICENSE-APACHE]: https://github.com/daxpedda/axum-server-dual-protocol/blob/v0.7.0/LICENSE-APACHE
129//! [`aws-lc-rs`]: https://docs.rs/aws-lc-rs/1
130//! [`axum`]: https://docs.rs/axum/0.7
131//! [`CryptoProvider`]: tokio_rustls::rustls::crypto::CryptoProvider
132//! [`hyper`]: https://docs.rs/hyper/1
133//! [`Router`]: https://docs.rs/axum/0.7/axum/struct.Router.html
134//! [`tower`]: https://docs.rs/tower/0.4
135
136mod dual_protocol;
137mod upgrade_http;
138
139pub use dual_protocol::{
140	bind_dual_protocol, from_tcp_dual_protocol, DualProtocolAcceptor, DualProtocolAcceptorFuture,
141	DualProtocolService, DualProtocolServiceFuture, Protocol, ServerExt,
142};
143pub use upgrade_http::{UpgradeHttp, UpgradeHttpFuture, UpgradeHttpLayer};
144pub use {
145	axum_server, bytes, http, http_body_util, tokio, tokio_rustls, tokio_util, tower_service,
146};