about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md13
-rw-r--r--TODO.md16
-rw-r--r--corgi/src/main.rs49
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();
+			}
+		}
+	}
+}