replace_host
This commit is contained in:
parent
db288728bd
commit
390be0b507
23
README.md
23
README.md
@ -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
|
||||||
|
3
conf.yml
3
conf.yml
@ -14,4 +14,5 @@ sites:
|
|||||||
enable_keep_alive: true # Enable keep-alive connections (optional, default - true)
|
enable_keep_alive: true # Enable keep-alive connections (optional, default - true)
|
||||||
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)
|
@ -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);
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user