Move bind::NormalizeUri to its own module in proxy::http (#94)
Split proxy infrastructure from `bind` In order to simplify `bind.rs`, this change moves `NormalizeUri` into its own module, `proxy::http::normalize_uri`. This will later become part of the "client stack" built from `proxy::http`.
This commit is contained in:
parent
bbf296668b
commit
567b1b7ff2
60
src/bind.rs
60
src/bind.rs
|
@ -20,7 +20,11 @@ use ctx::transport::TlsStatus;
|
||||||
use watch_service::{WatchService, Rebind};
|
use watch_service::{WatchService, Rebind};
|
||||||
|
|
||||||
/// An HTTP `Service` that is created for each `Endpoint` and `Protocol`.
|
/// An HTTP `Service` that is created for each `Endpoint` and `Protocol`.
|
||||||
pub type Stack<B> = proxy::http::orig_proto::Upgrade<NormalizeUri<WatchTls<B>>>;
|
pub type Stack<B> = proxy::http::orig_proto::Upgrade<
|
||||||
|
proxy::http::normalize_uri::Service<
|
||||||
|
WatchTls<B>
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
|
||||||
type WatchTls<B> = WatchService<tls::ConditionalClientConfig, RebindTls<B>>;
|
type WatchTls<B> = WatchService<tls::ConditionalClientConfig, RebindTls<B>>;
|
||||||
|
|
||||||
|
@ -131,20 +135,6 @@ pub enum Host {
|
||||||
NoAuthority,
|
NoAuthority,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rewrites HTTP/1.x requests so that their URIs are in a canonical form.
|
|
||||||
///
|
|
||||||
/// The following transformations are applied:
|
|
||||||
/// - If an absolute-form URI is received, it must replace
|
|
||||||
/// the host header (in accordance with RFC7230#section-5.4)
|
|
||||||
/// - If the request URI is not in absolute form, it is rewritten to contain
|
|
||||||
/// the authority given in the `Host:` header, or, failing that, from the
|
|
||||||
/// request's original destination according to `SO_ORIGINAL_DST`.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct NormalizeUri<S> {
|
|
||||||
inner: S,
|
|
||||||
was_absolute_form: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RebindTls<B> {
|
pub struct RebindTls<B> {
|
||||||
bind: Bind<ctx::Proxy, B>,
|
bind: Bind<ctx::Proxy, B>,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
|
@ -293,7 +283,10 @@ where
|
||||||
// and request URI are not in agreement, or are not present.
|
// and request URI are not in agreement, or are not present.
|
||||||
//
|
//
|
||||||
// TODO move this into proxy::Client?
|
// TODO move this into proxy::Client?
|
||||||
let normalize_uri = NormalizeUri::new(watch_tls, protocol.was_absolute_form());
|
let normalize_uri = proxy::http::normalize_uri::Service::new(
|
||||||
|
watch_tls,
|
||||||
|
protocol.was_absolute_form()
|
||||||
|
);
|
||||||
|
|
||||||
// Upgrade HTTP/1.1 requests to be HTTP/2 if the endpoint supports HTTP/2.
|
// Upgrade HTTP/1.1 requests to be HTTP/2 if the endpoint supports HTTP/2.
|
||||||
proxy::http::orig_proto::Upgrade::new(normalize_uri, protocol.is_http2())
|
proxy::http::orig_proto::Upgrade::new(normalize_uri, protocol.is_http2())
|
||||||
|
@ -356,41 +349,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ===== impl NormalizeUri =====
|
|
||||||
|
|
||||||
impl<S> NormalizeUri<S> {
|
|
||||||
fn new(inner: S, was_absolute_form: bool) -> Self {
|
|
||||||
Self { inner, was_absolute_form }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, B> tower::Service for NormalizeUri<S>
|
|
||||||
where
|
|
||||||
S: tower::Service<Request = http::Request<B>>,
|
|
||||||
{
|
|
||||||
type Request = S::Request;
|
|
||||||
type Response = S::Response;
|
|
||||||
type Error = S::Error;
|
|
||||||
type Future = S::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), S::Error> {
|
|
||||||
self.inner.poll_ready()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, mut request: S::Request) -> Self::Future {
|
|
||||||
if request.version() != http::Version::HTTP_2 &&
|
|
||||||
// Skip normalizing the URI if it was received in
|
|
||||||
// absolute form.
|
|
||||||
!self.was_absolute_form
|
|
||||||
{
|
|
||||||
proxy::http::h1::normalize_our_view_of_uri(&mut request);
|
|
||||||
}
|
|
||||||
self.inner.call(request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ===== impl Binding =====
|
|
||||||
|
|
||||||
impl<B> tower::Service for BoundService<B>
|
impl<B> tower::Service for BoundService<B>
|
||||||
where
|
where
|
||||||
B: tower_h2::Body + Send + 'static,
|
B: tower_h2::Body + Send + 'static,
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub(super) mod glue;
|
pub(super) mod glue;
|
||||||
pub mod h1;
|
pub mod h1;
|
||||||
|
pub mod normalize_uri;
|
||||||
|
pub mod orig_proto;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
pub mod upgrade;
|
pub mod upgrade;
|
||||||
pub mod orig_proto;
|
|
||||||
|
|
||||||
pub use self::client::{Client, Error as ClientError};
|
pub use self::client::{Client, Error as ClientError};
|
||||||
pub use self::glue::HttpBody as Body;
|
pub use self::glue::HttpBody as Body;
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
use http;
|
||||||
|
use futures::Poll;
|
||||||
|
|
||||||
|
use super::h1::normalize_our_view_of_uri;
|
||||||
|
use svc;
|
||||||
|
|
||||||
|
/// Rewrites HTTP/1.x requests so that their URIs are in a canonical form.
|
||||||
|
///
|
||||||
|
/// The following transformations are applied:
|
||||||
|
/// - If an absolute-form URI is received, it must replace
|
||||||
|
/// the host header (in accordance with RFC7230#section-5.4)
|
||||||
|
/// - If the request URI is not in absolute form, it is rewritten to contain
|
||||||
|
/// the authority given in the `Host:` header, or, failing that, from the
|
||||||
|
/// request's original destination according to `SO_ORIGINAL_DST`.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct Service<S> {
|
||||||
|
inner: S,
|
||||||
|
was_absolute_form: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== impl Service =====
|
||||||
|
|
||||||
|
impl<S> Service<S> {
|
||||||
|
pub fn new(inner: S, was_absolute_form: bool) -> Self {
|
||||||
|
Self { inner, was_absolute_form }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, B> svc::Service for Service<S>
|
||||||
|
where
|
||||||
|
S: svc::Service<Request = http::Request<B>>,
|
||||||
|
{
|
||||||
|
type Request = S::Request;
|
||||||
|
type Response = S::Response;
|
||||||
|
type Error = S::Error;
|
||||||
|
type Future = S::Future;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), S::Error> {
|
||||||
|
self.inner.poll_ready()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, mut request: S::Request) -> Self::Future {
|
||||||
|
if request.version() != http::Version::HTTP_2 &&
|
||||||
|
// Skip normalizing the URI if it was received in
|
||||||
|
// absolute form.
|
||||||
|
!self.was_absolute_form
|
||||||
|
{
|
||||||
|
normalize_our_view_of_uri(&mut request);
|
||||||
|
}
|
||||||
|
self.inner.call(request)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue