Skip to content

Commit 3d1de7b

Browse files
authored
Expose the SNI when possible. (#2943)
Grabs the SNI from TLS connections and saves to ConenctionMeta struct. Provides useful methods for exracting the SNI from requests. Closes #2942
1 parent 3ccfd8b commit 3d1de7b

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
3+
[*.rs]
4+
insert_final_newline = true
5+
trim_trailing_whitespace = true
6+
indent_style = space
7+
indent_size = 4
8+
tab_width = 4

core/lib/src/listener/connection.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub trait Connection: AsyncRead + AsyncWrite + Send + Unpin {
2222
/// Defaults to an empty vector to indicate that no certificates were
2323
/// presented.
2424
fn certificates(&self) -> Option<Certificates<'_>> { None }
25+
26+
fn server_name(&self) -> Option<&str> { None }
2527
}
2628

2729
impl<A: Connection, B: Connection> Connection for Either<A, B> {

core/lib/src/request/request.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,19 @@ pub(crate) struct ConnectionMeta {
4545
pub peer_endpoint: Option<Endpoint>,
4646
#[cfg_attr(not(feature = "mtls"), allow(dead_code))]
4747
pub peer_certs: Option<Arc<Certificates<'static>>>,
48+
#[cfg_attr(feature = "tls", allow(dead_code))]
49+
pub server_name: Option<String>,
4850
}
4951

5052
impl ConnectionMeta {
51-
pub fn new(endpoint: io::Result<Endpoint>, certs: Option<Certificates<'_>>) -> Self {
53+
pub fn new(
54+
endpoint: io::Result<Endpoint>,
55+
certs: Option<Certificates<'_>>,
56+
server_name: Option<&str>) -> Self {
5257
ConnectionMeta {
5358
peer_endpoint: endpoint.ok(),
5459
peer_certs: certs.map(|c| c.into_owned()).map(Arc::new),
60+
server_name: server_name.map(|s| s.to_string()),
5561
}
5662
}
5763
}
@@ -295,6 +301,16 @@ impl<'r> Request<'r> {
295301
self.state.host.as_ref()
296302
}
297303

304+
/// Returns the resolved SNI server name requested in the TLS handshake, if
305+
/// any.
306+
///
307+
/// Ideally, this will match the `Host` header in the request.
308+
#[cfg(feature = "tls")]
309+
#[inline(always)]
310+
pub fn sni(&mut self) -> Option<&str> {
311+
self.connection.server_name.as_deref()
312+
}
313+
298314
/// Sets the host of `self` to `host`.
299315
///
300316
/// # Example

core/lib/src/server.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ impl Rocket<Orbit> {
172172
let (listener, rocket, server) = (listener.clone(), self.clone(), server.clone());
173173
spawn_inspect(|e| log_server_error(&**e), async move {
174174
let conn = listener.connect(accept).race_io(rocket.shutdown()).await?;
175-
let meta = ConnectionMeta::new(conn.endpoint(), conn.certificates());
175+
let meta = ConnectionMeta::new(
176+
conn.endpoint(),
177+
conn.certificates(),
178+
conn.server_name()
179+
);
176180
let service = service_fn(|mut req| {
177181
let upgrade = hyper::upgrade::on(&mut req);
178182
let (parts, incoming) = req.into_parts();
@@ -205,7 +209,7 @@ impl Rocket<Orbit> {
205209
while let Some(mut conn) = stream.accept().race_io(rocket.shutdown()).await? {
206210
let rocket = rocket.clone();
207211
spawn_inspect(|e: &io::Error| log_server_error(e), async move {
208-
let meta = ConnectionMeta::new(conn.endpoint(), None);
212+
let meta = ConnectionMeta::new(conn.endpoint(), None, None);
209213
let rx = conn.rx.cancellable(rocket.shutdown.clone());
210214
let response = rocket.clone()
211215
.service(conn.parts, rx, None, meta)

core/lib/src/tls/listener.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,13 @@ impl<C: Connection> Connection for TlsStream<C> {
9696
#[cfg(not(feature = "mtls"))]
9797
None
9898
}
99+
100+
fn server_name(&self) -> Option<&str> {
101+
#[cfg(feature = "tls")] {
102+
self.get_ref().1.server_name()
103+
}
104+
105+
#[cfg(not(feature = "tls"))]
106+
None
107+
}
99108
}

0 commit comments

Comments
 (0)