diff options
author | gennyble <gen@nyble.dev> | 2025-03-11 14:42:29 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2025-03-11 14:42:29 -0500 |
commit | 912ce0966c42f126d7a37c88e442e16a30308415 (patch) | |
tree | cd17b5f93c57f7ef6b17c99f776503d5ddf3803b | |
download | corgi-912ce0966c42f126d7a37c88e442e16a30308415.tar.gz corgi-912ce0966c42f126d7a37c88e442e16a30308415.zip |
works :)
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .rustfmt.toml | 2 | ||||
-rw-r--r-- | Cargo.lock | 365 | ||||
-rw-r--r-- | Cargo.toml | 17 | ||||
-rw-r--r-- | src/main.rs | 131 |
5 files changed, 516 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..4639247 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,2 @@ +hard_tabs = true +chain_width = 100 diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..55b19f3 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,365 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "corgi" +version = "0.1.0" +dependencies = [ + "http-body-util", + "hyper", + "hyper-util", + "tokio", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "http" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a761d192fbf18bdef69f5ceedd0d1333afcbda0ee23840373b8317570d23c65" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "windows-sys", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..206071d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "corgi" +version = "0.1.0" +edition = "2024" + +[dependencies] +http-body-util = "0.1.3" +hyper-util = { version = "0.1.10", features = ["tokio"] } + +[dependencies.tokio] +version = "1.44.0" +features = ["rt", "rt-multi-thread", "io-std", "net", "process"] + +[dependencies.hyper] +version = "1.6.0" +default-features = false +features = ["server", "http1"] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..72abb0e --- /dev/null +++ b/src/main.rs @@ -0,0 +1,131 @@ +use core::panic; +use std::{net::SocketAddr, pin::Pin}; + +use http_body_util::{BodyExt, Full}; +use hyper::{ + Request, Response, StatusCode, + body::{Body, Bytes, Incoming}, + server::conn::http1, + service::Service, +}; +use hyper_util::rt::TokioIo; +use tokio::{net::TcpListener, process::Command, runtime::Runtime}; + +fn main() { + let rt = Runtime::new().unwrap(); + rt.block_on(async { run().await }); +} + +async fn run() { + let addr = SocketAddr::from(([0, 0, 0, 0], 2562)); + let listen = TcpListener::bind(addr).await.unwrap(); + + let svc = Svc {}; + + loop { + let (stream, _caddr) = listen.accept().await.unwrap(); + let io = TokioIo::new(stream); + let svc_clone = svc.clone(); + tokio::task::spawn( + async move { http1::Builder::new().serve_connection(io, svc_clone).await }, + ); + } +} + +#[derive(Clone, Debug)] +struct Svc {} + +impl Service<Request<Incoming>> for Svc { + type Response = Response<Full<Bytes>>; + type Error = hyper::Error; + type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>; + + fn call(&self, req: Request<Incoming>) -> Self::Future { + fn make<B: Into<Bytes>>(b: B) -> Result<Response<Full<Bytes>>, hyper::Error> { + Ok(Response::builder().body(Full::new(b.into())).unwrap()) + } + + Box::pin(async { Ok(Self::handle(req).await) }) + } +} + +impl Svc { + async fn handle(req: Request<Incoming>) -> Response<Full<Bytes>> { + let method = req.method().as_str().to_ascii_uppercase(); + let path = req.uri().path().to_owned(); + let headers = req.headers().clone(); + let body = req.into_body().collect().await.unwrap().to_bytes(); + let content_length = body.len(); + + let mut cmd = Command::new("/usr/lib/cgit/cgit.cgi"); + cmd.env("PATH_INFO", path).env("REQUEST_METHOD", method); + + for (header, value) in headers { + if let Some(header) = header { + let hname = header.as_str(); + let hvalue = value.to_str().unwrap(); + cmd.env(hname.to_ascii_uppercase(), hvalue); + + if hname.to_ascii_lowercase() == "user-agent" { + println!("USER_AGENT: {hvalue}"); + } + } + } + + /*if content_length > 0 { + cmd.env("CONTENT_LENGTH", content_length.to_string()); + }*/ + + let output = cmd.output().await.unwrap(); + let response_raw = output.stdout; + let mut response = Response::builder(); + + println!("{}", String::from_utf8_lossy(&response_raw)); + + let mut curr = response_raw.as_slice(); + let mut status = None; + let mut headers = vec![]; + let body = loop { + let nl = curr.iter().position(|b| *b == b'\n').expect("no nl in header"); + let line = &curr[..nl]; + + let colon = line.iter().position(|b| *b == b':').expect("no colon in header"); + let key = &line[..colon]; + let value = &line[colon + 1..]; + headers.push((key, value)); + + let key_string = String::from_utf8_lossy(key); + if key_string == "Status" { + let value_string = String::from_utf8_lossy(value); + if let Some((raw_code, raw_msg)) = value_string.trim().split_once(' ') { + let code: usize = raw_code.parse().unwrap(); + status = Some((code, raw_msg.to_owned())); + } + } + + // Body next + if curr[nl + 1] == b'\n' || (curr[nl + 1] == b'\r' && curr[nl + 2] == b'\n') { + break &curr[nl + 2..]; + } else { + curr = &curr[nl + 1..]; + } + }; + + match status { + None => response = response.status(StatusCode::OK), + Some((code, _status)) => { + response = response.status(StatusCode::from_u16(code as u16).unwrap()); + } + } + + for (key, value) in headers { + response = response.header(key.to_vec(), value.to_vec()); + } + + response.body(Full::new(Bytes::from(body.to_vec()))).unwrap() + } + + fn make<B: Into<Bytes>>(b: B) -> Response<Full<Bytes>> { + Response::builder().body(Full::new(b.into())).unwrap() + } +} |