Skip to content

Commit 1d31765

Browse files
committed
Also allow getting authority from the request URI's authority.
Signed-off-by: Ryan Levick <[email protected]>
1 parent be24451 commit 1d31765

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

crates/trigger-http2/src/server.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::{collections::HashMap, future::Future, io::IsTerminal, net::SocketAddr, sync::Arc};
22

3-
use anyhow::Context;
4-
use http::{uri::Scheme, Request, Response, StatusCode, Uri};
3+
use anyhow::{bail, Context};
4+
use http::{
5+
uri::{Authority, Scheme},
6+
Request, Response, StatusCode, Uri,
7+
};
58
use http_body_util::BodyExt;
69
use hyper::{
710
body::{Bytes, Incoming},
@@ -359,29 +362,39 @@ impl HttpServer {
359362
/// The incoming request's scheme and authority
360363
///
361364
/// The incoming request's URI is relative to the server, so we need to set the scheme and authority.
362-
/// The `Host` header is used to set the authority. This function will error if no `Host` header is
363-
/// present or if it is not parsable as an `Authority`.
365+
/// Either the `Host` header or the request's URI's authority is used as the source of truth for the authority.
366+
/// This function will error if the authority cannot be unambiguously determined.
364367
fn set_req_uri(req: &mut Request<Body>, scheme: Scheme) -> anyhow::Result<()> {
365368
let uri = req.uri().clone();
366369
let mut parts = uri.into_parts();
367370
let headers = req.headers();
368-
let host_header = headers
371+
let header_authority = headers
369372
.get(http::header::HOST)
370-
.context("missing 'Host' header")?
371-
.to_str()
372-
.context("'Host' header is not valid UTF-8")?;
373-
let authority = host_header
374-
.parse()
375-
.context("'Host' header contains an invalid authority")?;
376-
// Ensure that if `req.authority` is set, it matches what was in the `Host` header
377-
// https://github.com/hyperium/hyper/issues/1612
378-
if let Some(a) = parts.authority.as_ref() {
379-
if a != &authority {
380-
return Err(anyhow::anyhow!(
381-
"authority in 'Host' header does not match authority in URI"
382-
));
373+
.map(|h| -> anyhow::Result<Authority> {
374+
let host_header = h.to_str().context("'Host' header is not valid UTF-8")?;
375+
host_header
376+
.parse()
377+
.context("'Host' header contains an invalid authority")
378+
})
379+
.transpose()?;
380+
let uri_authority = parts.authority;
381+
382+
// Get authority either from request URI or from 'Host' header
383+
let authority = match (header_authority, uri_authority) {
384+
(None, None) => bail!("no 'Host' header present in request"),
385+
(None, Some(a)) => a,
386+
(Some(a), None) => a,
387+
(Some(a1), Some(a2)) => {
388+
// Ensure that if `req.authority` is set, it matches what was in the `Host` header
389+
// https://github.com/hyperium/hyper/issues/1612
390+
if a1 != a2 {
391+
return Err(anyhow::anyhow!(
392+
"authority in 'Host' header does not match authority in URI"
393+
));
394+
}
395+
a1
383396
}
384-
}
397+
};
385398
parts.scheme = Some(scheme);
386399
parts.authority = Some(authority);
387400
*req.uri_mut() = Uri::from_parts(parts).unwrap();

0 commit comments

Comments
 (0)