this repo has no description

feat: implement server

ptr.pet a48b86a0

verified
+1
.gitignore
···
+
/target
+62
Cargo.lock
···
+
# This file is automatically @generated by Cargo.
+
# It is not intended for manual editing.
+
version = 4
+
+
[[package]]
+
name = "ascii"
+
version = "1.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
+
+
[[package]]
+
name = "chunked_transfer"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901"
+
+
[[package]]
+
name = "clickee-proxy"
+
version = "0.1.0"
+
dependencies = [
+
"tiny_http",
+
"tinyget",
+
]
+
+
[[package]]
+
name = "httpdate"
+
version = "1.0.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+
[[package]]
+
name = "log"
+
version = "0.4.28"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+
+
[[package]]
+
name = "tiny_http"
+
version = "0.12.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
+
dependencies = [
+
"ascii",
+
"chunked_transfer",
+
"httpdate",
+
"log",
+
]
+
+
[[package]]
+
name = "tinyget"
+
version = "1.1.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5205be93938f3ae916c773ffa3361eaf3b0ee4d40f3752da46d8b1d5311e7285"
+
dependencies = [
+
"urlencoding",
+
]
+
+
[[package]]
+
name = "urlencoding"
+
version = "2.1.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+8
Cargo.toml
···
+
[package]
+
name = "clickee-proxy"
+
version = "0.1.0"
+
edition = "2024"
+
+
[dependencies]
+
tiny_http = "0.12.0"
+
tinyget = "1.1.2"
+47
src/main.rs
···
+
use tiny_http::{Response, Server};
+
+
fn main() {
+
let clickee_urls_raw = std::env::var("CLICKEE_URLS").expect("CLICKEE_URLS must be set");
+
let clickee_urls = clickee_urls_raw.split(",").collect::<Vec<_>>();
+
let port = std::env::var("PORT")
+
.unwrap_or_else(|_| "8000".to_string())
+
.parse::<u16>()
+
.expect("PORT must be a number");
+
let server = Server::http(("0.0.0.0", port)).unwrap();
+
+
for request in server.incoming_requests() {
+
let get_header = |name| {
+
request
+
.headers()
+
.iter()
+
.find(|h| h.field.equiv(name))
+
.map(|h| h.value.to_string())
+
};
+
let ip = get_header("x-real-ip")
+
.or_else(|| request.remote_addr().map(|a| a.to_string()))
+
.unwrap_or_else(|| "unknown".to_string());
+
let ua = get_header("user-agent").unwrap_or_else(|| "unknown".to_string());
+
+
let mut sent_click = false;
+
for url in clickee_urls.iter() {
+
match tinyget::get(*url).send_lazy() {
+
Ok(_) => {
+
sent_click = true;
+
break;
+
}
+
Err(err) => println!("clickee ({url}) not online (error: {err}), using next one"),
+
}
+
}
+
+
if sent_click {
+
println!("clicker clicked: {ua} from {ip}");
+
} else {
+
println!("no clickee available");
+
}
+
+
let resp = Response::empty(sent_click.then_some(200).unwrap_or(502));
+
if let Err(err) = request.respond(resp) {
+
println!("error responding to clicker: {err}");
+
}
+
}
+
}