changed how to support multiple domains and support client authentication directly by rustls using split server_config

This commit is contained in:
Jun Kurihara 2022-10-14 22:45:13 +09:00
commit 512690fce5
No known key found for this signature in database
GPG key ID: 48ADFD173ED22B03
11 changed files with 218 additions and 184 deletions

View file

@ -1,6 +1,12 @@
// Highly motivated by https://github.com/felipenoris/hyper-reverse-proxy
use super::{utils_headers::*, utils_request::*, utils_synth_response::*};
use crate::{backend::UpstreamGroup, error::*, globals::Globals, log::*, utils::ServerNameBytesExp};
use crate::{
backend::{Backend, UpstreamGroup},
error::*,
globals::Globals,
log::*,
utils::ServerNameBytesExp,
};
use hyper::{
client::connect::Connect,
header::{self, HeaderValue},
@ -35,26 +41,11 @@ where
listen_addr: SocketAddr,
tls_enabled: bool,
tls_server_name: Option<ServerNameBytesExp>,
tls_client_auth_result: Option<std::result::Result<(), ClientCertsError>>,
) -> Result<Response<Body>> {
////////
let mut log_data = MessageLog::from(&req);
log_data.client_addr(&client_addr);
//////
// First check client auth result if exist
if let Some(res) = tls_client_auth_result {
match res {
Err(ClientCertsError::ClientCertRequired(_)) => {
// Client cert is required for the TLS server name
return self.return_with_error_log(StatusCode::FORBIDDEN, &mut log_data);
}
Err(ClientCertsError::InconsistentClientCert(_)) => {
// Client cert provided was inconsistent to the TLS server name
return self.return_with_error_log(StatusCode::BAD_REQUEST, &mut log_data);
}
_ => (),
}
}
// Here we start to handle with server_name
let server_name = if let Ok(v) = req.parse_host() {
@ -133,7 +124,7 @@ where
if res_backend.status() != StatusCode::SWITCHING_PROTOCOLS {
// Generate response to client
if self.generate_response_forwarded(&mut res_backend).is_ok() {
if self.generate_response_forwarded(&mut res_backend, backend).is_ok() {
log_data.status_code(&res_backend.status()).output();
return Ok(res_backend);
} else {
@ -191,7 +182,11 @@ where
////////////////////////////////////////////////////
// Functions to generate messages
fn generate_response_forwarded<B: core::fmt::Debug>(&self, response: &mut Response<B>) -> Result<()> {
fn generate_response_forwarded<B: core::fmt::Debug>(
&self,
response: &mut Response<B>,
chosen_backend: &Backend,
) -> Result<()> {
let headers = response.headers_mut();
remove_connection_header(headers);
remove_hop_header(headers);
@ -199,7 +194,8 @@ where
#[cfg(feature = "http3")]
{
if self.globals.http3 {
// TODO: Workaround for avoid h3 for client authentication
if self.globals.http3 && chosen_backend.client_ca_cert_path.is_none() {
if let Some(port) = self.globals.https_port {
add_header_entry_overwrite_if_exist(
headers,
@ -210,6 +206,15 @@ where
),
)?;
}
} else {
// remove alt-svc to disallow requests via http3
headers.remove(header::ALT_SVC.as_str());
}
}
#[cfg(not(feature = "http3"))]
{
if let Some(port) = self.globals.https_port {
headers.remove(header::ALT_SVC.as_str());
}
}