replace_host

This commit is contained in:
MeexReay 2024-11-23 15:05:48 +03:00
parent db288728bd
commit 390be0b507
5 changed files with 55 additions and 52 deletions

View File

@ -12,28 +12,7 @@ TODO:
- Remove panics - Remove panics
- Creating trees of flowgate - Creating trees of flowgate
## Config ## IP forwarding types
Default `conf.yml`:
```yml
http_host: localhost:80 # Http server host
https_host: localhost:443 # Https server host
threadpool_size: 10 # Threadpool size (count of threads that accept requests) (optional, default - 10)
connection_timeout: 10 # Read and write timeout of connections in seconds (optional, default - 10)
incoming_ip_forwarding: none # Read IP forwarding on incoming connections (optional, default - none)
sites:
- domain: localhost # Site domain (use wildcard matching)
host: localhost:8080 # Http server host
ip_forwarding: simple # IP forwarding method type (optional, default - header)
enable_keep_alive: true # Enable keep-alive connections (optional, default - true)
support_keep_alive: true # Does server supports keep-alive connections (optional, default - true)
# ssl_cert: "/path/to/public/certificate.txt" # Ssl public certificate file (optional)
# ssl_key: "/path/to/private/key.txt" # Ssl private key file (optional)
```
### IP forwaring types
- None (`none`):\ - None (`none`):\
Do nothing Do nothing

View File

@ -15,3 +15,4 @@ sites:
support_keep_alive: true # Does server supports keep-alive connections (optional, default - true) support_keep_alive: true # Does server supports keep-alive connections (optional, default - true)
# ssl_cert: "/path/to/public/certificate.txt" # Ssl public certificate file (optional) # ssl_cert: "/path/to/public/certificate.txt" # Ssl public certificate file (optional)
# ssl_key: "/path/to/private/key.txt" # Ssl private key file (optional) # ssl_key: "/path/to/private/key.txt" # Ssl private key file (optional)
replace_host: "pansangg.github.io" # Replace Host header in requests to server (optional)

View File

@ -12,7 +12,8 @@ pub struct SiteConfig {
pub ssl: Option<SslCert>, pub ssl: Option<SslCert>,
pub enable_keep_alive: bool, pub enable_keep_alive: bool,
pub support_keep_alive: bool, pub support_keep_alive: bool,
pub ip_forwarding: IpForwarding pub ip_forwarding: IpForwarding,
pub replace_host: Option<String>
} }
impl SiteConfig { impl SiteConfig {
@ -105,6 +106,8 @@ impl Config {
.map(|o| o.as_str()).flatten() .map(|o| o.as_str()).flatten()
.map(|o| IpForwarding::from_name(o)).flatten() .map(|o| IpForwarding::from_name(o)).flatten()
.unwrap_or(IpForwarding::Header("X-Real-IP".to_string())), .unwrap_or(IpForwarding::Header("X-Real-IP".to_string())),
replace_host: s.get("replace_host")
.map(|o| o.as_str()).flatten().map(|o| o.to_string()),
}; };
sites.push(site); sites.push(site);

View File

@ -186,19 +186,19 @@ impl FlowgateServer {
addr: SocketAddr, addr: SocketAddr,
https: bool https: bool
) -> Option<()> { ) -> Option<()> {
let mut connected = Self::read_request(config.clone(), stream, addr, https, None)?; let mut conn = Self::read_request(config.clone(), stream, addr, https, None)?;
if connected.2 && connected.1.enable_keep_alive { if conn.2 && conn.1.enable_keep_alive {
loop { loop {
if !connected.1.support_keep_alive { if !conn.1.support_keep_alive {
connected.0.close(); conn.0.close();
connected.0 = connected.1.connect()?; conn.0 = conn.1.connect()?;
} }
connected = Self::read_request(config.clone(), stream, addr, https, Some(connected))?; conn = Self::read_request(config.clone(), stream, addr, https, Some(conn))?;
} }
} }
connected.0.close(); conn.0.close();
stream.close(); stream.close();
Some(()) Some(())
@ -209,7 +209,7 @@ impl FlowgateServer {
stream: &'a mut (impl Read + Write + Closeable), stream: &'a mut (impl Read + Write + Closeable),
addr: SocketAddr, addr: SocketAddr,
https: bool, https: bool,
connected: Option<(TcpStream, SiteConfig, bool, String)> conn: Option<(TcpStream, SiteConfig, bool, String)>
) -> Option<(TcpStream, SiteConfig, bool, String)> { ) -> Option<(TcpStream, SiteConfig, bool, String)> {
let mut addr = addr; let mut addr = addr;
@ -275,8 +275,6 @@ impl FlowgateServer {
head.truncate(head.len() - 4); head.truncate(head.len() - 4);
} }
// println!("read client head");
if head.is_empty() { return None; } if head.is_empty() { return None; }
let head_str = String::from_utf8(head.clone()).ok()?; let head_str = String::from_utf8(head.clone()).ok()?;
@ -298,7 +296,7 @@ impl FlowgateServer {
} }
} }
let mut connected: (TcpStream, SiteConfig, bool, String) = if connected.is_none() { let mut conn: (TcpStream, SiteConfig, bool, String) = if conn.is_none() {
let mut host = String::new(); let mut host = String::new();
let mut keep_alive = false; let mut keep_alive = false;
@ -314,7 +312,7 @@ impl FlowgateServer {
(site.connect()?, site, keep_alive, host) (site.connect()?, site, keep_alive, host)
} else { } else {
connected? conn?
}; };
let content_length = headers let content_length = headers
@ -327,7 +325,31 @@ impl FlowgateServer {
let mut reqbuf: Vec<u8> = Vec::new(); let mut reqbuf: Vec<u8> = Vec::new();
match &connected.1.ip_forwarding { if let Some(replace_host) = conn.1.replace_host.clone() {
let mut new_head = Vec::new();
let mut is_status = true;
for line in head_str.split("\r\n") {
if is_status {
new_head.append(&mut line.as_bytes().to_vec());
is_status = false;
} else {
new_head.append(&mut b"\r\n".to_vec());
let (key, _) = line.split_once(": ")?;
if key.to_lowercase() == "host" {
new_head.append(&mut key.as_bytes().to_vec());
new_head.append(&mut b": ".to_vec());
new_head.append(&mut replace_host.as_bytes().to_vec());
} else {
new_head.append(&mut line.as_bytes().to_vec());
}
}
}
head = new_head;
}
match &conn.1.ip_forwarding {
IpForwarding::Header(header) => { IpForwarding::Header(header) => {
reqbuf.append(&mut status.to_string().as_bytes().to_vec()); reqbuf.append(&mut status.to_string().as_bytes().to_vec());
reqbuf.append(&mut b"\r\n".to_vec()); reqbuf.append(&mut b"\r\n".to_vec());
@ -362,12 +384,13 @@ impl FlowgateServer {
reqbuf.append(&mut head.clone()); reqbuf.append(&mut head.clone());
reqbuf.append(&mut b"\r\n\r\n".to_vec()); reqbuf.append(&mut b"\r\n\r\n".to_vec());
}, },
IpForwarding::None => { } IpForwarding::None => {
reqbuf.append(&mut head.clone());
reqbuf.append(&mut b"\r\n\r\n".to_vec());
}
} }
connected.0.write_all(&reqbuf).ok()?; conn.0.write_all(&reqbuf).ok()?;
// println!("wrote client head to server");
if content_length > 0 { if content_length > 0 {
let mut read = 0usize; let mut read = 0usize;
@ -376,22 +399,20 @@ impl FlowgateServer {
if size == 0 { break } if size == 0 { break }
read += size; read += size;
buf.truncate(size); buf.truncate(size);
connected.0.write_all(&buf).ok()?; conn.0.write_all(&buf).ok()?;
buf = vec![0; 4096]; buf = vec![0; 4096];
if read == content_length { break } if read == content_length { break }
} }
} }
// println!("wrote client body to server"); if conn.1.support_keep_alive {
if connected.1.support_keep_alive {
let mut head = Vec::new(); let mut head = Vec::new();
{ {
let mut buf = [0; 1]; let mut buf = [0; 1];
let mut counter = 0; let mut counter = 0;
while let Ok(1) = connected.0.read(&mut buf) { while let Ok(1) = conn.0.read(&mut buf) {
let byte = buf[0]; let byte = buf[0];
head.push(byte); head.push(byte);
@ -427,7 +448,7 @@ impl FlowgateServer {
if content_length > 0 { if content_length > 0 {
let mut read = 0usize; let mut read = 0usize;
let mut buf = vec![0; 4096]; let mut buf = vec![0; 4096];
while let Ok(size) = connected.0.read(&mut buf) { while let Ok(size) = conn.0.read(&mut buf) {
if size == 0 { break } if size == 0 { break }
read += size; read += size;
buf.truncate(size); buf.truncate(size);
@ -438,14 +459,12 @@ impl FlowgateServer {
} }
} else { } else {
let mut buf = Vec::new(); let mut buf = Vec::new();
connected.0.read_to_end(&mut buf).ok()?; conn.0.read_to_end(&mut buf).ok()?;
stream.write_all(&buf).ok()?; stream.write_all(&buf).ok()?;
} }
// println!("wrote server response to client"); info!("{addr} > {} {}://{}{}", status_seq[0], if https { "https" } else { "http" }, conn.3, status_seq[1]);
info!("{addr} > {} {}://{}{}", status_seq[0], if https { "https" } else { "http" }, connected.3, status_seq[1]); Some(conn)
Some(connected)
} }
} }

View File

@ -23,6 +23,7 @@ fn on_message(config: Arc<RwLock<Config>>, data: Value) -> Option<()> {
enable_keep_alive: data.get("enable_keep_alive")?.as_bool()?, enable_keep_alive: data.get("enable_keep_alive")?.as_bool()?,
support_keep_alive: data.get("support_keep_alive")?.as_bool()?, support_keep_alive: data.get("support_keep_alive")?.as_bool()?,
ip_forwarding: IpForwarding::from_name(data.get("ip_forwarding")?.as_str()?)?, ip_forwarding: IpForwarding::from_name(data.get("ip_forwarding")?.as_str()?)?,
replace_host: data.get("replace_host").map(|o| o.as_str()).flatten().map(|o| o.to_string()),
ssl: None ssl: None
}); });
} }