diff options
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | TODO.md | 16 | ||||
-rw-r--r-- | corgi/src/main.rs | 49 |
3 files changed, 57 insertions, 21 deletions
diff --git a/README.md b/README.md index 635e574..32c8f3d 100644 --- a/README.md +++ b/README.md @@ -45,16 +45,3 @@ Any environmental variable may be overridden if it is set in the configuration file, except the `CONTENT_LENGTH` envar. [rfc]: https://datatracker.ietf.org/doc/html/rfc3875 - -corgi has a cgi module system as an alternate for spawning a new process -on every request. it creates a new thread, loads a dynamic library into -it, and executes functions from that library. since it's a function, -corgi doesn't need to send all the data on standard input but can instead -pass a cleaner, more structured struct with the headers and body still -separate from one another. - -the module system is designed to, hopefully, allow more efficient cgi -scripts than the conventional approach while still having the same -flexibility. it has not yet been benchmarked. - -see [smalldog](smalldog/README.md) for more details on how it works. \ No newline at end of file diff --git a/TODO.md b/TODO.md index a439640..d7c4aa2 100644 --- a/TODO.md +++ b/TODO.md @@ -10,11 +10,6 @@ a `catch_unwind`? there are complications with the first one, but perhaps we can make it work? -(5) Crate For The Module System - so we don't have to copy the weird structs. and also so maybe we - can make it safer? A C header, too, maybe? that just define the - struct. and really some kind of documentation, probably. - DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) ======================================================================= @@ -25,4 +20,13 @@ DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) DONE :) (2) Support Matching CGI Based On Path The other requirement for git-http-backend, which needs to - trigger on the regex `/.+/(info/refs|git-upload-pack)` \ No newline at end of file + trigger on the regex `/.+/(info/refs|git-upload-pack)` + +(5) Crate For The Module System + so we don't have to copy the weird structs. and also so maybe we + can make it safer? A C header, too, maybe? that just define the + struct. and really some kind of documentation, probably. + + EWONTFIX + lol. module system was ripped out because it turns out there is no + good way to handle more than one request concurrently, it seems. diff --git a/corgi/src/main.rs b/corgi/src/main.rs index b8b23de..ba7195b 100644 --- a/corgi/src/main.rs +++ b/corgi/src/main.rs @@ -147,8 +147,8 @@ impl Svc { // Collect things we need from the request before we eat it's body let method = req.method().as_str().to_ascii_uppercase(); let version = req.version(); - let path = req.uri().path().to_owned(); - let query = req.uri().query().unwrap_or_default().to_owned(); + let path = url_decode(req.uri().path().to_owned(), false).unwrap(); + let query = url_decode(req.uri().query().unwrap_or_default().to_owned(), false).unwrap(); let headers = req.headers().clone(); let body = req.into_body().collect().await.unwrap().to_bytes().to_vec(); @@ -280,3 +280,48 @@ impl Svc { ret } } + +// Ripped and modified from gennyble/mavourings query.rs +fn url_decode<S: AsRef<str>>(urlencoded: S, plus_as_space: bool) -> Option<String> { + let urlencoded = urlencoded.as_ref(); + let mut uncoded: Vec<u8> = Vec::with_capacity(urlencoded.len()); + + let mut chars = urlencoded.chars().peekable(); + loop { + let mut utf8_bytes = [0; 4]; + match chars.next() { + Some('+') => match plus_as_space { + true => uncoded.push(b' '), + false => uncoded.push(b'+'), + }, + Some('%') => match chars.peek() { + Some(c) if c.is_ascii_hexdigit() => { + let upper = chars.next().unwrap(); + + if let Some(lower) = chars.peek() { + if lower.is_ascii_hexdigit() { + let upper = upper.to_digit(16).unwrap(); + let lower = chars.next().unwrap().to_digit(16).unwrap(); + + uncoded.push(upper as u8 * 16 + lower as u8); + continue; + } + } + + uncoded.push(b'%'); + uncoded.extend_from_slice(upper.encode_utf8(&mut utf8_bytes).as_bytes()); + } + _ => { + uncoded.push(b'%'); + } + }, + Some(c) => { + uncoded.extend_from_slice(c.encode_utf8(&mut utf8_bytes).as_bytes()); + } + None => { + uncoded.shrink_to_fit(); + return String::from_utf8(uncoded).ok(); + } + } + } +} |