use bytesname trait to explicitly convert &str/string to ascii lower-cased byte names of server / path
This commit is contained in:
parent
4d590f328f
commit
7bd9040637
10 changed files with 49 additions and 46 deletions
|
|
@ -1,7 +1,10 @@
|
|||
mod upstream;
|
||||
mod upstream_opts;
|
||||
|
||||
use crate::log::*;
|
||||
use crate::{
|
||||
log::*,
|
||||
utils::{BytesName, PathNameBytesExp, ServerNameBytesExp},
|
||||
};
|
||||
use rustc_hash::FxHashMap as HashMap;
|
||||
use std::{
|
||||
fs::File,
|
||||
|
|
@ -17,11 +20,6 @@ use tokio_rustls::rustls::{
|
|||
pub use upstream::{ReverseProxy, Upstream, UpstreamGroup};
|
||||
pub use upstream_opts::UpstreamOption;
|
||||
|
||||
// Server name (hostname or ip address) and path name representation in backends
|
||||
// For searching hashmap or key list by exact or longest-prefix matching
|
||||
pub type ServerNameBytesExp = Vec<u8>; // lowercase ascii bytes
|
||||
pub type PathNameBytesExp = Vec<u8>; // lowercase ascii bytes
|
||||
|
||||
/// Struct serving information to route incoming connections, like server name to be handled and tls certs/keys settings.
|
||||
pub struct Backend {
|
||||
pub app_name: String,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use super::{PathNameBytesExp, UpstreamOption};
|
||||
use super::{BytesName, PathNameBytesExp, UpstreamOption};
|
||||
use crate::log::*;
|
||||
use rand::Rng;
|
||||
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
|
||||
|
|
@ -19,8 +19,7 @@ impl ReverseProxy {
|
|||
pub fn get<'a>(&self, path_str: impl Into<Cow<'a, str>>) -> Option<&UpstreamGroup> {
|
||||
// trie使ってlongest prefix match させてもいいけどルート記述は少ないと思われるので、
|
||||
// コスト的にこの程度で十分
|
||||
let path_lc = path_str.into().to_ascii_lowercase();
|
||||
let path_bytes = path_lc.as_bytes();
|
||||
let path_bytes = &(path_str.to_path_name_vec())[..];
|
||||
|
||||
let matched_upstream = self
|
||||
.upstream
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use super::toml::{ConfigToml, ReverseProxyOption};
|
||||
use crate::{
|
||||
backend::{Backend, PathNameBytesExp, ReverseProxy, UpstreamGroup, UpstreamOption},
|
||||
backend::{Backend, ReverseProxy, UpstreamGroup, UpstreamOption},
|
||||
constants::*,
|
||||
error::*,
|
||||
globals::*,
|
||||
log::*,
|
||||
utils::{BytesName, PathNameBytesExp},
|
||||
};
|
||||
use clap::Arg;
|
||||
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
|
||||
|
|
@ -91,7 +92,7 @@ pub fn parse_opts(globals: &mut Globals) -> std::result::Result<(), anyhow::Erro
|
|||
// each app
|
||||
for (app_name, app) in apps.0.iter() {
|
||||
ensure!(app.server_name.is_some(), "Missing server_name");
|
||||
let server_name = app.server_name.as_ref().unwrap().to_ascii_lowercase();
|
||||
let server_name_string = app.server_name.as_ref().unwrap();
|
||||
|
||||
// TLS settings
|
||||
let (tls_cert_path, tls_cert_key_path, https_redirection) = if app.tls.is_none() {
|
||||
|
|
@ -122,10 +123,10 @@ pub fn parse_opts(globals: &mut Globals) -> std::result::Result<(), anyhow::Erro
|
|||
let reverse_proxy = get_reverse_proxy(app.reverse_proxy.as_ref().unwrap())?;
|
||||
|
||||
globals.backends.apps.insert(
|
||||
server_name.as_bytes().to_vec(),
|
||||
server_name_string.to_server_name_vec(),
|
||||
Backend {
|
||||
app_name: app_name.to_owned(),
|
||||
server_name: server_name.to_owned(),
|
||||
server_name: server_name_string.to_ascii_lowercase(),
|
||||
reverse_proxy,
|
||||
|
||||
tls_cert_path,
|
||||
|
|
@ -133,7 +134,7 @@ pub fn parse_opts(globals: &mut Globals) -> std::result::Result<(), anyhow::Erro
|
|||
https_redirection,
|
||||
},
|
||||
);
|
||||
info!("Registering application: {} ({})", app_name, server_name);
|
||||
info!("Registering application: {} ({})", app_name, server_name_string);
|
||||
}
|
||||
|
||||
// default backend application for plaintext http requests
|
||||
|
|
@ -194,8 +195,8 @@ fn get_reverse_proxy(rp_settings: &[ReverseProxyOption]) -> std::result::Result<
|
|||
let mut upstream: HashMap<PathNameBytesExp, UpstreamGroup> = HashMap::default();
|
||||
rp_settings.iter().for_each(|rpo| {
|
||||
let path = match &rpo.path {
|
||||
Some(p) => p.as_bytes().to_ascii_lowercase(),
|
||||
None => "/".as_bytes().to_ascii_lowercase(),
|
||||
Some(p) => p.to_path_name_vec(),
|
||||
None => "/".to_path_name_vec(),
|
||||
};
|
||||
|
||||
let elem = UpstreamGroup {
|
||||
|
|
@ -204,7 +205,7 @@ fn get_reverse_proxy(rp_settings: &[ReverseProxyOption]) -> std::result::Result<
|
|||
replace_path: rpo
|
||||
.replace_path
|
||||
.as_ref()
|
||||
.map_or_else(|| None, |v| Some(v.as_bytes().to_ascii_lowercase())),
|
||||
.map_or_else(|| None, |v| Some(v.to_path_name_vec())),
|
||||
cnt: Default::default(),
|
||||
lb: Default::default(),
|
||||
opts: {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
// Highly motivated by https://github.com/felipenoris/hyper-reverse-proxy
|
||||
use super::{utils_headers::*, utils_request::*, utils_synth_response::*};
|
||||
use crate::{
|
||||
backend::{ServerNameBytesExp, UpstreamGroup},
|
||||
error::*,
|
||||
globals::Globals,
|
||||
log::*,
|
||||
};
|
||||
use crate::{backend::UpstreamGroup, error::*, globals::Globals, log::*, utils::ServerNameBytesExp};
|
||||
use hyper::{
|
||||
client::connect::Connect,
|
||||
header::{self, HeaderValue},
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@ mod proxy;
|
|||
mod utils;
|
||||
|
||||
use crate::{
|
||||
backend::{Backend, Backends, ServerNameBytesExp},
|
||||
backend::{Backend, Backends},
|
||||
config::parse_opts,
|
||||
constants::*,
|
||||
error::*,
|
||||
globals::*,
|
||||
log::*,
|
||||
proxy::Proxy,
|
||||
utils::ServerNameBytesExp,
|
||||
};
|
||||
use futures::future::select_all;
|
||||
use handler::HttpMessageHandler;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::Proxy;
|
||||
use crate::{backend::ServerNameBytesExp, error::*, log::*};
|
||||
use crate::{error::*, log::*, utils::ServerNameBytesExp};
|
||||
use bytes::{Buf, Bytes};
|
||||
use h3::{quic::BidiStream, server::RequestStream};
|
||||
use hyper::{client::connect::Connect, Body, Request, Response};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// use super::proxy_handler::handle_request;
|
||||
use crate::{backend::ServerNameBytesExp, error::*, globals::Globals, handler::HttpMessageHandler, log::*};
|
||||
use crate::{error::*, globals::Globals, handler::HttpMessageHandler, log::*, utils::ServerNameBytesExp};
|
||||
use hyper::{client::connect::Connect, server::conn::Http, service::service_fn, Body, Request};
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use tokio::{
|
||||
|
|
@ -61,7 +61,6 @@ where
|
|||
}
|
||||
debug!("Request incoming: current # {}", request_count.current());
|
||||
|
||||
// let inner = tls_server_name.map_or_else(|| None, |v| Some(v.as_bytes().to_ascii_lowercase()));
|
||||
self.globals.runtime_handle.clone().spawn(async move {
|
||||
timeout(
|
||||
self.globals.proxy_timeout + Duration::from_secs(1),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::proxy_main::{LocalExecutor, Proxy};
|
||||
use crate::{constants::*, error::*, log::*};
|
||||
use crate::{constants::*, error::*, log::*, utils::BytesName};
|
||||
use hyper::{client::connect::Connect, server::conn::Http};
|
||||
use rustls::ServerConfig;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -66,7 +66,7 @@ where
|
|||
let (_, conn) = stream.get_ref();
|
||||
let server_name = conn.sni_hostname();
|
||||
debug!("HTTP/2 or 1.1: SNI in ClientHello: {:?}", server_name);
|
||||
let server_name = server_name.map_or_else(|| None, |v| Some(v.as_bytes().to_ascii_lowercase()));
|
||||
let server_name = server_name.map_or_else(|| None, |v| Some(v.to_server_name_vec()));
|
||||
if server_name.is_none(){
|
||||
Err(anyhow!("No SNI is given"))
|
||||
} else {
|
||||
|
|
@ -140,7 +140,7 @@ where
|
|||
Err(_) => continue
|
||||
};
|
||||
let new_server_name = match hsd_downcast.server_name {
|
||||
Some(sn) => sn.as_bytes().to_ascii_lowercase(),
|
||||
Some(sn) => sn.to_server_name_vec(),
|
||||
None => {
|
||||
warn!("HTTP/3 no SNI is given");
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,31 @@
|
|||
use bytes::{Buf, Bytes};
|
||||
// Server name (hostname or ip address) and path name representation in backends
|
||||
// For searching hashmap or key list by exact or longest-prefix matching
|
||||
pub type ServerNameBytesExp = Vec<u8>; // lowercase ascii bytes
|
||||
|
||||
// #[derive(Clone, Debug)]
|
||||
// pub struct ServerNameBytesExp(Vec<u8>);
|
||||
|
||||
pub type PathNameBytesExp = Vec<u8>; // lowercase ascii bytes
|
||||
|
||||
pub trait BytesName {
|
||||
type Output: Buf;
|
||||
fn to_bytes(self) -> Self::Output;
|
||||
fn to_ascii_lowercase_bytes(self) -> Self::Output;
|
||||
type OutputSv: Send + Sync + 'static;
|
||||
type OutputPath;
|
||||
fn to_server_name_vec(self) -> Self::OutputSv;
|
||||
fn to_path_name_vec(self) -> Self::OutputPath;
|
||||
}
|
||||
|
||||
impl<T: Into<String>> BytesName for T {
|
||||
type Output = Bytes;
|
||||
impl<'a, T: Into<std::borrow::Cow<'a, str>>> BytesName for T {
|
||||
type OutputSv = ServerNameBytesExp;
|
||||
type OutputPath = PathNameBytesExp;
|
||||
|
||||
fn to_bytes(self) -> Self::Output {
|
||||
let b = self.into().bytes().collect::<Vec<u8>>();
|
||||
Bytes::from(b)
|
||||
fn to_server_name_vec(self) -> Self::OutputSv {
|
||||
let name = self.into().bytes().collect::<Vec<u8>>().to_ascii_lowercase();
|
||||
name
|
||||
}
|
||||
|
||||
fn to_ascii_lowercase_bytes(self) -> Self::Output {
|
||||
let b = self.into().bytes().collect::<Vec<u8>>().to_ascii_lowercase();
|
||||
Bytes::from(b)
|
||||
fn to_path_name_vec(self) -> Self::OutputPath {
|
||||
let name = self.into().bytes().collect::<Vec<u8>>().to_ascii_lowercase();
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,10 +35,10 @@ mod tests {
|
|||
#[test]
|
||||
fn bytes_name_str_works() {
|
||||
let s = "OK_string";
|
||||
let bn = s.to_bytes();
|
||||
let bn_lc = s.to_ascii_lowercase_bytes();
|
||||
let bn = s.to_path_name_vec();
|
||||
let bn_lc = s.to_server_name_vec();
|
||||
|
||||
assert_eq!(Bytes::from(s.as_bytes()), bn);
|
||||
assert_eq!(Bytes::from("ok_string"), bn_lc);
|
||||
assert_eq!(Vec::from(s.as_bytes()), bn);
|
||||
assert_eq!(Vec::from(s.as_bytes()), bn_lc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
mod bytes_name;
|
||||
mod socket_addr;
|
||||
|
||||
pub use bytes_name::{BytesName, PathNameBytesExp, ServerNameBytesExp};
|
||||
pub use socket_addr::ToCanonical;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue