implement native-tls client
This commit is contained in:
parent
0741990154
commit
48a84a77cb
12 changed files with 90 additions and 69 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue