Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not strictly related to the change, but I ran into some annoying check_style issues and it wasn't immediately clear how to properly run the checks on my machine.

This should help with general file formatting, trailing whitespace, and line endings at the end of files for those who use an editorconfig editor plugin. I highly recommend it!


[*.rs]
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
tab_width = 4
2 changes: 2 additions & 0 deletions core/lib/src/listener/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub trait Connection: AsyncRead + AsyncWrite + Send + Unpin {
/// Defaults to an empty vector to indicate that no certificates were
/// presented.
fn certificates(&self) -> Option<Certificates<'_>> { None }

fn server_name(&self) -> Option<&str> { None }
}

impl<A: Connection, B: Connection> Connection for Either<A, B> {
Expand Down
18 changes: 17 additions & 1 deletion core/lib/src/request/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ pub(crate) struct ConnectionMeta {
pub peer_endpoint: Option<Endpoint>,
#[cfg_attr(not(feature = "mtls"), allow(dead_code))]
pub peer_certs: Option<Arc<Certificates<'static>>>,
#[cfg_attr(feature = "tls", allow(dead_code))]
pub server_name: Option<String>,
}

impl ConnectionMeta {
pub fn new(endpoint: io::Result<Endpoint>, certs: Option<Certificates<'_>>) -> Self {
pub fn new(
endpoint: io::Result<Endpoint>,
certs: Option<Certificates<'_>>,
server_name: Option<&str>) -> Self {
ConnectionMeta {
peer_endpoint: endpoint.ok(),
peer_certs: certs.map(|c| c.into_owned()).map(Arc::new),
server_name: server_name.map(|s| s.to_string()),
}
}
}
Expand Down Expand Up @@ -295,6 +301,16 @@ impl<'r> Request<'r> {
self.state.host.as_ref()
}

/// Returns the resolved SNI server name requested in the TLS handshake, if
/// any.
///
/// Ideally, this will match the `Host` header in the request.
#[cfg(feature = "tls")]
#[inline(always)]
pub fn sni(&mut self) -> Option<&str> {
self.connection.server_name.as_deref()
}

/// Sets the host of `self` to `host`.
///
/// # Example
Expand Down
8 changes: 6 additions & 2 deletions core/lib/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ impl Rocket<Orbit> {
let (listener, rocket, server) = (listener.clone(), self.clone(), server.clone());
spawn_inspect(|e| log_server_error(&**e), async move {
let conn = listener.connect(accept).race_io(rocket.shutdown()).await?;
let meta = ConnectionMeta::new(conn.endpoint(), conn.certificates());
let meta = ConnectionMeta::new(
conn.endpoint(),
conn.certificates(),
conn.server_name()
);
let service = service_fn(|mut req| {
let upgrade = hyper::upgrade::on(&mut req);
let (parts, incoming) = req.into_parts();
Expand Down Expand Up @@ -205,7 +209,7 @@ impl Rocket<Orbit> {
while let Some(mut conn) = stream.accept().race_io(rocket.shutdown()).await? {
let rocket = rocket.clone();
spawn_inspect(|e: &io::Error| log_server_error(e), async move {
let meta = ConnectionMeta::new(conn.endpoint(), None);
let meta = ConnectionMeta::new(conn.endpoint(), None, None);
let rx = conn.rx.cancellable(rocket.shutdown.clone());
let response = rocket.clone()
.service(conn.parts, rx, None, meta)
Expand Down
9 changes: 9 additions & 0 deletions core/lib/src/tls/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,13 @@ impl<C: Connection> Connection for TlsStream<C> {
#[cfg(not(feature = "mtls"))]
None
}

fn server_name(&self) -> Option<&str> {
#[cfg(feature = "tls")] {
self.get_ref().1.server_name()
}

#[cfg(not(feature = "tls"))]
None
}
}
Loading