wip: manipulate response header

This commit is contained in:
Jun Kurihara 2023-11-28 16:56:23 +09:00
commit f0b0dbc252
No known key found for this signature in database
GPG key ID: D992B3E3DE1DED23
4 changed files with 57 additions and 54 deletions

View file

@ -10,4 +10,4 @@ pub(crate) use self::{
upstream::{PathManager, Upstream, UpstreamCandidates}, upstream::{PathManager, Upstream, UpstreamCandidates},
upstream_opts::UpstreamOption, upstream_opts::UpstreamOption,
}; };
pub(crate) use backend_main::{BackendAppBuilderError, BackendAppManager}; pub(crate) use backend_main::{BackendApp, BackendAppBuilderError, BackendAppManager};

View file

@ -38,7 +38,7 @@ where
U: CryptoSource + Clone, U: CryptoSource + Clone,
{ {
// forwarder: Arc<Forwarder<T>>, // forwarder: Arc<Forwarder<T>>,
globals: Arc<Globals>, pub(super) globals: Arc<Globals>,
app_manager: Arc<BackendAppManager<U>>, app_manager: Arc<BackendAppManager<U>>,
} }
@ -155,7 +155,7 @@ where
tls_enabled, tls_enabled,
) { ) {
Err(e) => { Err(e) => {
error!("Failed to generate destination uri for backend application: {}", e); error!("Failed to generate upstream request for backend application: {}", e);
return Err(HttpError::FailedToGenerateUpstreamRequest(e.to_string())); return Err(HttpError::FailedToGenerateUpstreamRequest(e.to_string()));
} }
Ok(v) => v, Ok(v) => v,
@ -199,12 +199,12 @@ where
} }
if res_backend.status() != StatusCode::SWITCHING_PROTOCOLS { if res_backend.status() != StatusCode::SWITCHING_PROTOCOLS {
// // Generate response to client // Generate response to client
// if self.generate_response_forwarded(&mut res_backend, backend).is_err() { if let Err(e) = self.generate_response_forwarded(&mut res_backend, backend_app) {
// return self.return_with_error_log(StatusCode::INTERNAL_SERVER_ERROR, &mut log_data); error!("Failed to generate downstream response for clients: {}", e);
// } return Err(HttpError::FailedToGenerateDownstreamResponse(e.to_string()));
// log_data.status_code(&res_backend.status()).output(); }
// return Ok(res_backend); return Ok(res_backend);
} }
// // Handle StatusCode::SWITCHING_PROTOCOLS in response // // Handle StatusCode::SWITCHING_PROTOCOLS in response

View file

@ -2,9 +2,14 @@ use super::{
handler_main::HandlerContext, utils_headers::*, utils_request::apply_upstream_options_to_request_line, handler_main::HandlerContext, utils_headers::*, utils_request::apply_upstream_options_to_request_line,
HttpMessageHandler, HttpMessageHandler,
}; };
use crate::{backend::UpstreamCandidates, log::*, CryptoSource}; use crate::{
backend::{BackendApp, UpstreamCandidates},
constants::RESPONSE_HEADER_SERVER,
log::*,
CryptoSource,
};
use anyhow::{anyhow, ensure, Result}; use anyhow::{anyhow, ensure, Result};
use http::{header, uri::Scheme, HeaderValue, Request, Uri, Version}; use http::{header, uri::Scheme, HeaderValue, Request, Response, Uri, Version};
use std::net::SocketAddr; use std::net::SocketAddr;
impl<U> HttpMessageHandler<U> impl<U> HttpMessageHandler<U>
@ -15,51 +20,46 @@ where
// Functions to generate messages // Functions to generate messages
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// /// Manipulate a response message sent from a backend application to forward downstream to a client. /// Manipulate a response message sent from a backend application to forward downstream to a client.
// fn generate_response_forwarded<B>(&self, response: &mut Response<B>, chosen_backend: &Backend<U>) -> Result<()> { pub(super) fn generate_response_forwarded<B>(
// where &self,
// B: core::fmt::Debug, response: &mut Response<B>,
// { backend_app: &BackendApp<U>,
// let headers = response.headers_mut(); ) -> Result<()> {
// remove_connection_header(headers); let headers = response.headers_mut();
// remove_hop_header(headers); remove_connection_header(headers);
// add_header_entry_overwrite_if_exist(headers, "server", RESPONSE_HEADER_SERVER)?; remove_hop_header(headers);
add_header_entry_overwrite_if_exist(headers, "server", RESPONSE_HEADER_SERVER)?;
// #[cfg(any(feature = "http3-quinn", feature = "http3-s2n"))] #[cfg(any(feature = "http3-quinn", feature = "http3-s2n"))]
// { {
// // Manipulate ALT_SVC allowing h3 in response message only when mutual TLS is not enabled // Manipulate ALT_SVC allowing h3 in response message only when mutual TLS is not enabled
// // TODO: This is a workaround for avoiding a client authentication in HTTP/3 // TODO: This is a workaround for avoiding a client authentication in HTTP/3
// if self.globals.proxy_config.http3 if self.globals.proxy_config.http3 && backend_app.crypto_source.as_ref().is_some_and(|v| !v.is_mutual_tls()) {
// && chosen_backend if let Some(port) = self.globals.proxy_config.https_port {
// .crypto_source add_header_entry_overwrite_if_exist(
// .as_ref() headers,
// .is_some_and(|v| !v.is_mutual_tls()) header::ALT_SVC.as_str(),
// { format!(
// if let Some(port) = self.globals.proxy_config.https_port { "h3=\":{}\"; ma={}, h3-29=\":{}\"; ma={}",
// add_header_entry_overwrite_if_exist( port, self.globals.proxy_config.h3_alt_svc_max_age, port, self.globals.proxy_config.h3_alt_svc_max_age
// headers, ),
// header::ALT_SVC.as_str(), )?;
// format!( }
// "h3=\":{}\"; ma={}, h3-29=\":{}\"; ma={}", } else {
// port, self.globals.proxy_config.h3_alt_svc_max_age, port, self.globals.proxy_config.h3_alt_svc_max_age // remove alt-svc to disallow requests via http3
// ), headers.remove(header::ALT_SVC.as_str());
// )?; }
// } }
// } else { #[cfg(not(any(feature = "http3-quinn", feature = "http3-s2n")))]
// // remove alt-svc to disallow requests via http3 {
// headers.remove(header::ALT_SVC.as_str()); if self.globals.proxy_config.https_port.is_some() {
// } headers.remove(header::ALT_SVC.as_str());
// } }
// #[cfg(not(any(feature = "http3-quinn", feature = "http3-s2n")))] }
// {
// if let Some(port) = self.globals.proxy_config.https_port {
// headers.remove(header::ALT_SVC.as_str());
// }
// }
// Ok(()) Ok(())
// todo!() }
// }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
/// Manipulate a request message sent from a client to forward upstream to a backend application /// Manipulate a request message sent from a client to forward upstream to a backend application

View file

@ -25,6 +25,8 @@ pub enum HttpError {
#[error("Failed to add set-cookie header in response")] #[error("Failed to add set-cookie header in response")]
FailedToAddSetCookeInResponse, FailedToAddSetCookeInResponse,
#[error("Failed to generated downstream response: {0}")]
FailedToGenerateDownstreamResponse(String),
#[error(transparent)] #[error(transparent)]
Other(#[from] anyhow::Error), Other(#[from] anyhow::Error),
@ -41,6 +43,7 @@ impl From<HttpError> for StatusCode {
HttpError::NoUpstreamCandidates => StatusCode::NOT_FOUND, HttpError::NoUpstreamCandidates => StatusCode::NOT_FOUND,
HttpError::FailedToGenerateUpstreamRequest(_) => StatusCode::INTERNAL_SERVER_ERROR, HttpError::FailedToGenerateUpstreamRequest(_) => StatusCode::INTERNAL_SERVER_ERROR,
HttpError::FailedToAddSetCookeInResponse => StatusCode::INTERNAL_SERVER_ERROR, HttpError::FailedToAddSetCookeInResponse => StatusCode::INTERNAL_SERVER_ERROR,
HttpError::FailedToGenerateDownstreamResponse(_) => StatusCode::INTERNAL_SERVER_ERROR,
_ => StatusCode::INTERNAL_SERVER_ERROR, _ => StatusCode::INTERNAL_SERVER_ERROR,
} }
} }