Moved http proxy under the service module
This commit is contained in:
parent
f7ecafbc17
commit
31782be10d
@ -3,16 +3,6 @@ origin:
|
|||||||
domain:
|
domain:
|
||||||
store_dir_path: /tmp/domani_dev_env/domain
|
store_dir_path: /tmp/domani_dev_env/domain
|
||||||
builtins:
|
builtins:
|
||||||
foo:
|
|
||||||
kind: http_proxy
|
|
||||||
url: http://127.0.0.1:9000
|
|
||||||
request_headers:
|
|
||||||
- name: x-foo
|
|
||||||
value: BAR
|
|
||||||
- name: host
|
|
||||||
value: hi
|
|
||||||
- name: user-agent
|
|
||||||
value: ""
|
|
||||||
bar:
|
bar:
|
||||||
kind: git
|
kind: git
|
||||||
url: a
|
url: a
|
||||||
@ -21,6 +11,16 @@ domain:
|
|||||||
service:
|
service:
|
||||||
http:
|
http:
|
||||||
form_method: GET
|
form_method: GET
|
||||||
|
proxied_domains:
|
||||||
|
foo:
|
||||||
|
url: http://127.0.0.1:9000
|
||||||
|
request_headers:
|
||||||
|
- name: x-foo
|
||||||
|
value: BAR
|
||||||
|
- name: host
|
||||||
|
value: hi
|
||||||
|
- name: user-agent
|
||||||
|
value: ""
|
||||||
passphrase: foobar
|
passphrase: foobar
|
||||||
dns_records:
|
dns_records:
|
||||||
- kind: A
|
- kind: A
|
||||||
|
47
README.md
47
README.md
@ -68,29 +68,6 @@ domain:
|
|||||||
# # domain list, but will not be configurable in the web interface
|
# # domain list, but will not be configurable in the web interface
|
||||||
# public: false
|
# public: false
|
||||||
|
|
||||||
# An example built-in domain backed by an HTTP reverse-proxy to some other
|
|
||||||
# web-service. Requests to the backing service will automatically have
|
|
||||||
# X-Forwarded-For and (if HTTPS) X-Forwarded-Proto headers added to them.
|
|
||||||
#
|
|
||||||
# Proxies are currently limited in the following ways:
|
|
||||||
# * url must be to an http endpoint (not https)
|
|
||||||
# * dns.resolver_addr is ignored and the system-wide dns is used
|
|
||||||
#
|
|
||||||
#proxy.example.com:
|
|
||||||
# kind: http_proxy
|
|
||||||
# url: "http://some.other.service.com"
|
|
||||||
#
|
|
||||||
# # Extra headers to add to proxied requests
|
|
||||||
# request_headers:
|
|
||||||
# - name: Host
|
|
||||||
# value: "yet.another.service.com"
|
|
||||||
# - name: X-HEADER-TO-DELETE
|
|
||||||
# value: ""
|
|
||||||
#
|
|
||||||
# # If true then the built-in will be included in the web interface's
|
|
||||||
# # domain list, but will not be configurable in the web interface
|
|
||||||
# public: false
|
|
||||||
|
|
||||||
service:
|
service:
|
||||||
|
|
||||||
# Passphrase which must be given by users who are configuring new domains via
|
# Passphrase which must be given by users who are configuring new domains via
|
||||||
@ -123,10 +100,32 @@ service:
|
|||||||
|
|
||||||
# The address to listen for HTTP requests on. This must use port 80 if
|
# The address to listen for HTTP requests on. This must use port 80 if
|
||||||
# https_addr is set.
|
# https_addr is set.
|
||||||
#http_addr: "[::]:3030"
|
#http_addr: "[::]:3080"
|
||||||
|
|
||||||
# The address to listen for HTTPS requests on. This is optional.
|
# The address to listen for HTTPS requests on. This is optional.
|
||||||
#https_addr: "[::]:443"
|
#https_addr: "[::]:443"
|
||||||
|
|
||||||
|
#proxied_domains:
|
||||||
|
|
||||||
|
# An example built-in domain backed by an HTTP reverse-proxy to some
|
||||||
|
# other web-service. Requests to the backing service will automatically
|
||||||
|
# have X-Forwarded-For and (if HTTPS) X-Forwarded-Proto headers added to
|
||||||
|
# them.
|
||||||
|
#
|
||||||
|
# Proxies are currently limited in the following ways:
|
||||||
|
# * url must be to an http endpoint (not https)
|
||||||
|
# * dns.resolver_addr is ignored and the system-wide dns is used
|
||||||
|
#
|
||||||
|
#proxy.example.com:
|
||||||
|
# kind: http_proxy
|
||||||
|
# url: "http://some.other.service.com"
|
||||||
|
#
|
||||||
|
# # Extra headers to add to proxied requests
|
||||||
|
# request_headers:
|
||||||
|
# - name: Host
|
||||||
|
# value: "yet.another.service.com"
|
||||||
|
# - name: X-HEADER-TO-DELETE
|
||||||
|
# value: ""
|
||||||
```
|
```
|
||||||
|
|
||||||
The YAML config file can be passed to the Domani process via the `--config-path`
|
The YAML config file can be passed to the Domani process via the `--config-path`
|
||||||
|
@ -248,10 +248,6 @@ impl Manager for ManagerImpl {
|
|||||||
) -> Result<util::BoxByteStream, GetFileError> {
|
) -> Result<util::BoxByteStream, GetFileError> {
|
||||||
let settings = self.domain_store.get(domain)?.settings;
|
let settings = self.domain_store.get(domain)?.settings;
|
||||||
|
|
||||||
if let origin::Descr::HttpProxy { .. } = settings.origin_descr {
|
|
||||||
return Err(unexpected::Error::from("origin is proxy, can't serve file").into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = settings.process_path(path);
|
let path = settings.process_path(path);
|
||||||
|
|
||||||
let f = self
|
let f = self
|
||||||
|
10
src/main.rs
10
src/main.rs
@ -78,16 +78,6 @@ async fn main() {
|
|||||||
config.service.dns_records.push(primary_cname);
|
config.service.dns_records.push(primary_cname);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (domain, builtin_domain) in &config.domain.builtins {
|
|
||||||
if let domani::origin::Descr::HttpProxy { ref url, .. } =
|
|
||||||
builtin_domain.settings.origin_descr
|
|
||||||
{
|
|
||||||
if let Err(e) = domani::origin::proxy::validate_proxy_url(url) {
|
|
||||||
panic!("invalid config for builtin domain {domain}: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config
|
config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ mod config;
|
|||||||
mod descr;
|
mod descr;
|
||||||
pub mod git;
|
pub mod git;
|
||||||
pub mod mux;
|
pub mod mux;
|
||||||
pub mod proxy;
|
|
||||||
|
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use descr::Descr;
|
pub use descr::Descr;
|
||||||
|
@ -14,12 +14,6 @@ pub struct DescrHttpProxyHeader {
|
|||||||
pub enum Descr {
|
pub enum Descr {
|
||||||
#[serde(rename = "git")]
|
#[serde(rename = "git")]
|
||||||
Git { url: String, branch_name: String },
|
Git { url: String, branch_name: String },
|
||||||
|
|
||||||
#[serde(rename = "http_proxy")]
|
|
||||||
HttpProxy {
|
|
||||||
url: String,
|
|
||||||
request_headers: Vec<DescrHttpProxyHeader>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Descr {
|
impl Descr {
|
||||||
@ -38,18 +32,6 @@ impl Descr {
|
|||||||
h_update(url);
|
h_update(url);
|
||||||
h_update(branch_name);
|
h_update(branch_name);
|
||||||
}
|
}
|
||||||
Descr::HttpProxy {
|
|
||||||
url,
|
|
||||||
request_headers,
|
|
||||||
} => {
|
|
||||||
h_update("proxy");
|
|
||||||
h_update(url);
|
|
||||||
for h in request_headers {
|
|
||||||
h_update("header");
|
|
||||||
h_update(&h.name);
|
|
||||||
h_update(&h.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h.finalize().encode_hex::<String>()
|
h.finalize().encode_hex::<String>()
|
||||||
|
@ -57,15 +57,11 @@ impl FSStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deconstruct_descr(descr: &origin::Descr) -> (&str, &str) {
|
fn deconstruct_descr(descr: &origin::Descr) -> (&str, &str) {
|
||||||
if let origin::Descr::Git {
|
let origin::Descr::Git {
|
||||||
ref url,
|
ref url,
|
||||||
ref branch_name,
|
ref branch_name,
|
||||||
} = descr
|
} = descr;
|
||||||
{
|
(url, branch_name)
|
||||||
(url, branch_name)
|
|
||||||
} else {
|
|
||||||
panic!("non git descr passed in")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_repo_snapshot(
|
fn create_repo_snapshot(
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
use crate::error::unexpected::{self, Mappable};
|
|
||||||
use crate::{domain, origin};
|
|
||||||
use http::header::{HeaderName, HeaderValue};
|
|
||||||
use std::{net, str::FromStr};
|
|
||||||
|
|
||||||
// proxy is a special case because it is so tied to the underlying protocol that a request is
|
|
||||||
// being served on, it can't be abstracted out into a simple "get_file" operation like other
|
|
||||||
// origins.
|
|
||||||
|
|
||||||
pub fn validate_proxy_url(proxy_url: &str) -> unexpected::Result<()> {
|
|
||||||
let parsed_proxy_url =
|
|
||||||
http::Uri::from_str(proxy_url).or_unexpected_while("parsing proxy url {proxy_url}")?;
|
|
||||||
|
|
||||||
let scheme = parsed_proxy_url.scheme().map_unexpected_while(|| {
|
|
||||||
format!("expected a scheme of http in the proxy url {proxy_url}")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if scheme != "http" {
|
|
||||||
return Err(unexpected::Error::from(
|
|
||||||
format!("scheme of proxy url {proxy_url} should be 'http'",).as_str(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn serve_http_request(
|
|
||||||
settings: &domain::Settings,
|
|
||||||
client_ip: net::IpAddr,
|
|
||||||
mut req: hyper::Request<hyper::Body>,
|
|
||||||
req_is_https: bool,
|
|
||||||
) -> unexpected::Result<hyper::Response<hyper::Body>> {
|
|
||||||
let (url, request_headers) = if let origin::Descr::HttpProxy {
|
|
||||||
ref url,
|
|
||||||
ref request_headers,
|
|
||||||
} = settings.origin_descr
|
|
||||||
{
|
|
||||||
(url, request_headers)
|
|
||||||
} else {
|
|
||||||
panic!("non-proxy domain settings passed in: {settings:?}")
|
|
||||||
};
|
|
||||||
|
|
||||||
for header in request_headers {
|
|
||||||
let name: HeaderName = header
|
|
||||||
.name
|
|
||||||
.as_str()
|
|
||||||
.try_into()
|
|
||||||
.map_unexpected_while(|| format!("parsing header name {}", &header.name))?;
|
|
||||||
|
|
||||||
if header.value == "" {
|
|
||||||
req.headers_mut().remove(name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = HeaderValue::from_str(&header.value).map_unexpected_while(|| {
|
|
||||||
format!(
|
|
||||||
"parsing {} as value for header {}",
|
|
||||||
&header.value, &header.name
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
req.headers_mut().insert(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if req_is_https {
|
|
||||||
req.headers_mut()
|
|
||||||
.insert("x-forwarded-proto", HeaderValue::from_static("https"));
|
|
||||||
}
|
|
||||||
|
|
||||||
match hyper_reverse_proxy::call(client_ip, url, req).await {
|
|
||||||
Ok(res) => Ok(res),
|
|
||||||
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error
|
|
||||||
// manually
|
|
||||||
Err(e) => Err(unexpected::Error::from(
|
|
||||||
format!("error while proxying to {url}: {e:?}").as_str(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
mod config;
|
mod config;
|
||||||
|
mod proxy;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
mod tpl;
|
mod tpl;
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ use std::str::FromStr;
|
|||||||
use std::{future, net, sync};
|
use std::{future, net, sync};
|
||||||
|
|
||||||
use crate::error::unexpected;
|
use crate::error::unexpected;
|
||||||
use crate::{domain, origin, service, util};
|
use crate::{domain, service, util};
|
||||||
|
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
||||||
@ -158,34 +159,7 @@ impl<'svc> Service {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn serve_origin(
|
async fn serve_origin(&self, domain: domain::Name, req: Request<Body>) -> Response<Body> {
|
||||||
&self,
|
|
||||||
client_ip: net::IpAddr,
|
|
||||||
domain: domain::Name,
|
|
||||||
req: Request<Body>,
|
|
||||||
req_is_https: bool,
|
|
||||||
) -> Response<Body> {
|
|
||||||
let settings = match self.domain_manager.get_settings(&domain) {
|
|
||||||
Ok(domain::manager::GetSettingsResult { settings, .. }) => settings,
|
|
||||||
Err(domain::manager::GetSettingsError::NotFound) => {
|
|
||||||
return self.render_error_page(404, "Domain not found");
|
|
||||||
}
|
|
||||||
Err(domain::manager::GetSettingsError::Unexpected(e)) => {
|
|
||||||
return self.internal_error(
|
|
||||||
format!("failed to fetch settings for domain {domain}: {e}").as_str(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// if the domain is backed by a proxy then that is handled specially.
|
|
||||||
if let origin::Descr::HttpProxy { .. } = settings.origin_descr {
|
|
||||||
return origin::proxy::serve_http_request(&settings, client_ip, req, req_is_https)
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
self.internal_error(format!("proxying {domain}: {e}").as_str())
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut path_owned;
|
let mut path_owned;
|
||||||
let path = req.uri().path();
|
let path = req.uri().path();
|
||||||
|
|
||||||
@ -463,11 +437,28 @@ impl<'svc> Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a managed domain was given then serve that from its origin, which is possibly a proxy
|
// If a managed domain was given then serve that from its origin or a proxy.
|
||||||
if let Some(domain) = maybe_host {
|
if let Some(domain) = maybe_host {
|
||||||
return self
|
if let Some(proxied_domain_config) = self.config.http.proxied_domains.get(&domain) {
|
||||||
.serve_origin(client_ip, domain, req, req_is_https)
|
return service::http::proxy::serve_http_request(
|
||||||
.await;
|
proxied_domain_config,
|
||||||
|
client_ip,
|
||||||
|
req,
|
||||||
|
req_is_https,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
self.internal_error(
|
||||||
|
format!(
|
||||||
|
"serving {domain} via proxy {}: {e}",
|
||||||
|
proxied_domain_config.url.as_ref()
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.serve_origin(domain, req).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve main domani site
|
// Serve main domani site
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
use crate::domain;
|
||||||
|
use crate::error::unexpected::{self, Mappable};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{net, str::FromStr};
|
use serde_with::{serde_as, TryFromInto};
|
||||||
|
|
||||||
|
use std::{collections, net, str::FromStr};
|
||||||
|
|
||||||
fn default_http_addr() -> net::SocketAddr {
|
fn default_http_addr() -> net::SocketAddr {
|
||||||
net::SocketAddr::from_str("[::]:3030").unwrap()
|
net::SocketAddr::from_str("[::]:3030").unwrap()
|
||||||
@ -35,6 +40,105 @@ impl AsRef<hyper::Method> for ConfigFormMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ConfigProxiedDomainUrl(String);
|
||||||
|
|
||||||
|
impl AsRef<str> for ConfigProxiedDomainUrl {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
return &self.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ConfigProxiedDomainUrl> for String {
|
||||||
|
fn from(url: ConfigProxiedDomainUrl) -> Self {
|
||||||
|
url.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for ConfigProxiedDomainUrl {
|
||||||
|
type Error = unexpected::Error;
|
||||||
|
|
||||||
|
fn try_from(url: String) -> Result<Self, Self::Error> {
|
||||||
|
let parsed = http::Uri::from_str(url.as_str())
|
||||||
|
.or_unexpected_while("parsing proxy url {proxy_url}")?;
|
||||||
|
|
||||||
|
let scheme = parsed
|
||||||
|
.scheme()
|
||||||
|
.map_unexpected_while(|| format!("expected a scheme of http in the proxy url {url}"))?;
|
||||||
|
|
||||||
|
if scheme != "http" {
|
||||||
|
return Err(unexpected::Error::from(
|
||||||
|
format!("scheme of proxy url {url} should be 'http'",).as_str(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ConfigProxiedDomainUrl(url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct ConfigProxiedDomainRequestHeader {
|
||||||
|
pub name: String,
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ConfigProxiedDomainRequestHeaders(http::header::HeaderMap);
|
||||||
|
|
||||||
|
impl AsRef<http::header::HeaderMap> for ConfigProxiedDomainRequestHeaders {
|
||||||
|
fn as_ref(&self) -> &http::header::HeaderMap {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ConfigProxiedDomainRequestHeaders {
|
||||||
|
fn default() -> Self {
|
||||||
|
ConfigProxiedDomainRequestHeaders(http::header::HeaderMap::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<ConfigProxiedDomainRequestHeaders> for Vec<ConfigProxiedDomainRequestHeader> {
|
||||||
|
type Error = http::header::ToStrError;
|
||||||
|
|
||||||
|
fn try_from(h: ConfigProxiedDomainRequestHeaders) -> Result<Self, Self::Error> {
|
||||||
|
let mut v = vec![];
|
||||||
|
for (name, value) in &h.0 {
|
||||||
|
v.push(ConfigProxiedDomainRequestHeader {
|
||||||
|
name: name.to_string(),
|
||||||
|
value: value.to_str()?.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Vec<ConfigProxiedDomainRequestHeader>> for ConfigProxiedDomainRequestHeaders {
|
||||||
|
type Error = unexpected::Error;
|
||||||
|
|
||||||
|
fn try_from(v: Vec<ConfigProxiedDomainRequestHeader>) -> Result<Self, Self::Error> {
|
||||||
|
use http::header::{HeaderMap, HeaderName, HeaderValue};
|
||||||
|
|
||||||
|
let mut h = HeaderMap::new();
|
||||||
|
for pair in v {
|
||||||
|
let name: HeaderName = pair.name.parse().or_unexpected()?;
|
||||||
|
let value: HeaderValue = pair.value.parse().or_unexpected()?;
|
||||||
|
h.insert(name, value);
|
||||||
|
}
|
||||||
|
Ok(ConfigProxiedDomainRequestHeaders(h))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[serde_as]
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct ConfigProxiedDomain {
|
||||||
|
#[serde_as(as = "TryFromInto<String>")]
|
||||||
|
pub url: ConfigProxiedDomainUrl,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde_as(as = "TryFromInto<Vec<ConfigProxiedDomainRequestHeader>>")]
|
||||||
|
pub request_headers: ConfigProxiedDomainRequestHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(default = "default_http_addr")]
|
#[serde(default = "default_http_addr")]
|
||||||
@ -43,6 +147,9 @@ pub struct Config {
|
|||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub form_method: ConfigFormMethod,
|
pub form_method: ConfigFormMethod,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub proxied_domains: collections::HashMap<domain::Name, ConfigProxiedDomain>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@ -51,6 +158,7 @@ impl Default for Config {
|
|||||||
http_addr: default_http_addr(),
|
http_addr: default_http_addr(),
|
||||||
https_addr: None,
|
https_addr: None,
|
||||||
form_method: Default::default(),
|
form_method: Default::default(),
|
||||||
|
proxied_domains: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/service/http/proxy.rs
Normal file
36
src/service/http/proxy.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use crate::error::unexpected::{self};
|
||||||
|
use crate::service;
|
||||||
|
use http::header::HeaderValue;
|
||||||
|
use std::net;
|
||||||
|
|
||||||
|
pub async fn serve_http_request(
|
||||||
|
config: &service::http::ConfigProxiedDomain,
|
||||||
|
client_ip: net::IpAddr,
|
||||||
|
mut req: hyper::Request<hyper::Body>,
|
||||||
|
req_is_https: bool,
|
||||||
|
) -> unexpected::Result<hyper::Response<hyper::Body>> {
|
||||||
|
for (name, value) in config.request_headers.as_ref() {
|
||||||
|
if value == "" {
|
||||||
|
req.headers_mut().remove(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.headers_mut().insert(name, value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if req_is_https {
|
||||||
|
req.headers_mut()
|
||||||
|
.insert("x-forwarded-proto", HeaderValue::from_static("https"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = config.url.as_ref();
|
||||||
|
|
||||||
|
match hyper_reverse_proxy::call(client_ip, url, req).await {
|
||||||
|
Ok(res) => Ok(res),
|
||||||
|
// ProxyError doesn't actually implement Error :facepalm: so we have to format the error
|
||||||
|
// manually
|
||||||
|
Err(e) => Err(unexpected::Error::from(
|
||||||
|
format!("error while proxying to {url}: {e:?}").as_str(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
@ -56,11 +56,6 @@ impl TryFrom<domain::Settings> for FlatDomainSettings {
|
|||||||
res.domain_setting_origin_descr_git_url = Some(url);
|
res.domain_setting_origin_descr_git_url = Some(url);
|
||||||
res.domain_setting_origin_descr_git_branch_name = Some(branch_name);
|
res.domain_setting_origin_descr_git_branch_name = Some(branch_name);
|
||||||
}
|
}
|
||||||
origin::Descr::HttpProxy { .. } => {
|
|
||||||
return Err(unexpected::Error::from(
|
|
||||||
"proxy origins not supported for forms",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.domain_setting_add_path_prefix = v.add_path_prefix;
|
res.domain_setting_add_path_prefix = v.add_path_prefix;
|
||||||
|
Loading…
Reference in New Issue
Block a user