add: obtain original peer ip from headers

master
rrr-marble 4 years ago
parent 302a84f4b4
commit 989ab443b9

9
Cargo.lock generated

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "httparse"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
[[package]]
name = "myip"
version = "0.1.0"
dependencies = [
"httparse",
]

@ -6,3 +6,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
httparse = "1.5.1"

@ -1,7 +1,9 @@
use httparse;
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
fn main() {
println!("Replying with most probable peer's ip on port 7878");
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
for stream in listener.incoming() {
@ -11,6 +13,8 @@ fn main() {
}
}
// Reply to TCP streem with peer's IP
// if anyhting goes wrong, just slap 404 on it
fn handle_connection(mut stream: TcpStream) {
// make it 8k?
// https://stackoverflow.com/questions/686217/maximum-on-http-header-values
@ -18,20 +22,33 @@ fn handle_connection(mut stream: TcpStream) {
stream.read(&mut buffer).unwrap();
let get = b"GET / HTTP";
let (status_line, contents) = if buffer.starts_with(get) {
(
"HTTP/1.1 200 OK",
stream.peer_addr().unwrap().ip().to_string(),
)
} else {
(
let err404 = (
"HTTP/1.1 404 NOT FOUND",
"<html>\n<head><title>404 Not Found</title></head>\n\
<body bgcolor=\"white\">\n<center><h1>404 Not Found</h1></center>\n\
<hr>\n</body>\n</html>"
.to_string(),
)
);
// println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
let (status_line, contents) = if buffer.starts_with(get) {
let mut headers = [httparse::EMPTY_HEADER; 30];
let mut req = httparse::Request::new(&mut headers);
match req.parse(&buffer) {
Ok(_) => {
let peer_ip =
pick_ip(req).unwrap_or_else(|| stream.peer_addr().unwrap().ip().to_string());
("HTTP/1.1 200 OK", peer_ip)
}
Err(e) => {
eprintln!("{:?}", e);
err404
}
}
} else {
err404
};
// add date header formatted to rfc2822?
@ -49,3 +66,23 @@ fn handle_connection(mut stream: TcpStream) {
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
/// Pick most likely peer ip from request headers
fn pick_ip(req: httparse::Request) -> Option<String> {
// https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
// CF-Connecting-IP
// X-Forwarded-For
let mut ip = None;
for header in req.headers {
let name = header.name.to_lowercase();
if name == "CF-Connecting-IP".to_lowercase() {
ip = Some(String::from_utf8_lossy(header.value).to_string());
break;
} else if name == "X-Forwarded-For".to_lowercase() {
ip = Some(String::from_utf8_lossy(header.value).to_string());
}
}
ip
}

Loading…
Cancel
Save