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

mod dual_protocol;
mod upgrade_http;

pub use dual_protocol::{
	bind_dual_protocol, from_tcp_dual_protocol, DualProtocolAcceptor, DualProtocolAcceptorFuture,
	DualProtocolService, DualProtocolServiceFuture, Protocol, ServerExt,
};
pub use upgrade_http::{UpgradeHttp, UpgradeHttpFuture, UpgradeHttpLayer};
pub use {
	axum_server, bytes, http, http_body_util, tokio, tokio_rustls, tokio_util, tower_service,
};