implement native-tls client

This commit is contained in:
Jun Kurihara 2023-11-29 17:24:07 +09:00
commit 48a84a77cb
No known key found for this signature in database
GPG key ID: 48ADFD173ED22B03
12 changed files with 90 additions and 69 deletions

View file

@ -17,7 +17,7 @@ use crate::{
};
use derive_builder::Builder;
use http::{Request, Response, StatusCode};
use hyper_util::rt::TokioIo;
use hyper_util::{client::legacy::connect::Connect, rt::TokioIo};
use std::{net::SocketAddr, sync::Arc};
use tokio::{io::copy_bidirectional, time::timeout};
@ -34,19 +34,19 @@ pub(super) struct HandlerContext {
#[derive(Clone, Builder)]
/// HTTP message handler for requests from clients and responses from backend applications,
/// responsible to manipulate and forward messages to upstream backends and downstream clients.
// pub struct HttpMessageHandler<T, U>
pub struct HttpMessageHandler<U>
pub struct HttpMessageHandler<U, C>
where
C: Send + Sync + Connect + Clone + 'static,
U: CryptoSource + Clone,
{
forwarder: Arc<Forwarder>,
forwarder: Arc<Forwarder<C>>,
pub(super) globals: Arc<Globals>,
app_manager: Arc<BackendAppManager<U>>,
}
impl<U> HttpMessageHandler<U>
impl<U, C> HttpMessageHandler<U, C>
where
// T: Connect + Clone + Sync + Send + 'static,
C: Send + Sync + Connect + Clone + 'static,
U: CryptoSource + Clone,
{
/// Handle incoming request message from a client.

View file

@ -1,7 +1,4 @@
use super::{
handler_main::HandlerContext, utils_headers::*, utils_request::apply_upstream_options_to_request_line,
HttpMessageHandler,
};
use super::{handler_main::HandlerContext, utils_headers::*, utils_request::update_request_line, HttpMessageHandler};
use crate::{
backend::{BackendApp, UpstreamCandidates},
constants::RESPONSE_HEADER_SERVER,
@ -9,11 +6,13 @@ use crate::{
CryptoSource,
};
use anyhow::{anyhow, ensure, Result};
use http::{header, uri::Scheme, HeaderValue, Request, Response, Uri, Version};
use http::{header, HeaderValue, Request, Response, Uri};
use hyper_util::client::legacy::connect::Connect;
use std::net::SocketAddr;
impl<U> HttpMessageHandler<U>
impl<U, C> HttpMessageHandler<U, C>
where
C: Send + Sync + Connect + Clone + 'static,
U: CryptoSource + Clone,
{
////////////////////////////////////////////////////
@ -177,18 +176,7 @@ where
.insert(header::CONNECTION, HeaderValue::from_static("upgrade"));
}
// If not specified (force_httpXX_upstream) and https, version is preserved except for http/3
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 unless upstream option enabled.");
*req.version_mut() = Version::HTTP_11;
} else if req.version() == Version::HTTP_3 {
// HTTP/3 is always https
debug!("HTTP/3 is currently unsupported for request to upstream.");
*req.version_mut() = Version::HTTP_2;
}
apply_upstream_options_to_request_line(req, upstream_candidates)?;
update_request_line(req, upstream_chosen, upstream_candidates)?;
Ok(context)
}

View file

@ -1,6 +1,9 @@
use crate::backend::{UpstreamCandidates, UpstreamOption};
use crate::{
backend::{Upstream, UpstreamCandidates, UpstreamOption},
log::*,
};
use anyhow::{anyhow, ensure, Result};
use http::{header, Request};
use http::{header, uri::Scheme, Request, Version};
/// Trait defining parser of hostname
/// Inspect and extract hostname from either the request HOST header or request line
@ -50,18 +53,30 @@ impl<B> InspectParseHost for Request<B> {
////////////////////////////////////////////////////
// Functions to manipulate request line
/// Apply upstream options in request line, specified in the configuration
pub(super) fn apply_upstream_options_to_request_line<B>(
/// Update request line, e.g., version, and apply upstream options to request line, specified in the configuration
pub(super) fn update_request_line<B>(
req: &mut Request<B>,
upstream: &UpstreamCandidates,
upstream_chosen: &Upstream,
upstream_candidates: &UpstreamCandidates,
) -> anyhow::Result<()> {
for opt in upstream.options.iter() {
// If not specified (force_httpXX_upstream) and https, version is preserved except for http/3
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 unless upstream option enabled.");
*req.version_mut() = Version::HTTP_11;
} else if req.version() == Version::HTTP_3 {
// HTTP/3 is always https
debug!("HTTP/3 is currently unsupported for request to upstream.");
*req.version_mut() = Version::HTTP_2;
}
for opt in upstream_candidates.options.iter() {
match opt {
UpstreamOption::ForceHttp11Upstream => *req.version_mut() = http::Version::HTTP_11,
UpstreamOption::ForceHttp11Upstream => *req.version_mut() = 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() = http::Version::HTTP_2;
*req.version_mut() = Version::HTTP_2;
}
_ => (),
}