todo: add http2-only client for h2c case

This commit is contained in:
Jun Kurihara 2023-08-07 22:18:54 +09:00
commit f2c6d738b6
No known key found for this signature in database
GPG key ID: D992B3E3DE1DED23
5 changed files with 26 additions and 14 deletions

View file

@ -4,8 +4,8 @@ use crate::error::*;
pub enum UpstreamOption {
OverrideHost,
UpgradeInsecureRequests,
ConvertHttpsTo11,
ConvertHttpsTo2,
ForceHttp11Upstream,
ForceHttp2Upstream,
// TODO: Adds more options for heder override
}
impl TryFrom<&str> for UpstreamOption {
@ -14,8 +14,8 @@ impl TryFrom<&str> for UpstreamOption {
match val {
"override_host" => Ok(Self::OverrideHost),
"upgrade_insecure_requests" => Ok(Self::UpgradeInsecureRequests),
"convert_https_to_11" => Ok(Self::ConvertHttpsTo11),
"convert_https_to_2" => Ok(Self::ConvertHttpsTo2),
"force_http11_upstream" => Ok(Self::ForceHttp11Upstream),
"force_http2_upstream" => Ok(Self::ForceHttp2Upstream),
_ => Err(RpxyError::Other(anyhow!("Unsupported header option"))),
}
}

View file

@ -225,7 +225,8 @@ where
}
if !(upstream.iter().all(|(_, elem)| {
!(elem.opts.contains(&UpstreamOption::ConvertHttpsTo11) && elem.opts.contains(&UpstreamOption::ConvertHttpsTo2))
!(elem.opts.contains(&UpstreamOption::ForceHttp11Upstream)
&& elem.opts.contains(&UpstreamOption::ForceHttp2Upstream))
})) {
error!("Either one of force_http11 or force_http2 can be enabled");
return Err(RpxyError::ConfigBuild("Invalid upstream option setting"));

View file

@ -356,14 +356,20 @@ where
}
// If not specified (force_httpXX_upstream) and https, version is preserved except for http/3
apply_upstream_options_to_request_line(req, upstream_group)?;
// Maybe workaround: Change version to http/1.1 when destination scheme is http
if req.version() != Version::HTTP_11 && upstream_chosen.uri.scheme() == Some(&Scheme::HTTP) {
*req.version_mut() = Version::HTTP_11;
} else if req.version() == Version::HTTP_3 {
debug!("HTTP/3 is currently unsupported for request to upstream. Use HTTP/2.");
match req.version() {
Version::HTTP_3 => {
debug!("HTTP/3 is currently unsupported for request to upstream.");
*req.version_mut() = Version::HTTP_2;
}
_ => {
if upstream_chosen.uri.scheme() == Some(&Scheme::HTTP) {
// Change version to http/1.1 when destination scheme is http
debug!("Change version to http/1.1 when destination scheme is http.");
*req.version_mut() = Version::HTTP_11;
}
}
}
apply_upstream_options_to_request_line(req, upstream_group)?;
Ok(context)
}

View file

@ -11,8 +11,12 @@ use hyper::{header, Request};
pub(super) fn apply_upstream_options_to_request_line<B>(req: &mut Request<B>, upstream: &UpstreamGroup) -> Result<()> {
for opt in upstream.opts.iter() {
match opt {
UpstreamOption::ConvertHttpsTo11 => *req.version_mut() = hyper::Version::HTTP_11,
UpstreamOption::ConvertHttpsTo2 => *req.version_mut() = hyper::Version::HTTP_2,
UpstreamOption::ForceHttp11Upstream => *req.version_mut() = hyper::Version::HTTP_11,
UpstreamOption::ForceHttp2Upstream => {
// case: h2c -> https://www.rfc-editor.org/rfc/rfc9113.txt
// Upgrade from HTTP/1.1 to HTTP/2 is deprecated. So, http-2 prior knowledge is required.
*req.version_mut() = hyper::Version::HTTP_2;
}
_ => (),
}
}

View file

@ -70,6 +70,7 @@ where
.enable_http2()
.build();
// TODO: HTTP2 only client is needed for http2 cleartext case
let msg_handler = HttpMessageHandlerBuilder::default()
.forwarder(Arc::new(Client::builder().build::<_, hyper::Body>(connector)))
.globals(globals.clone())