diff options
Diffstat (limited to 'src/modules/finger.rs')
| -rw-r--r-- | src/modules/finger.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/modules/finger.rs b/src/modules/finger.rs new file mode 100644 index 0000000..c61cfbe --- /dev/null +++ b/src/modules/finger.rs @@ -0,0 +1,69 @@ +use { + crate::{response::success, route::track_mount}, + std::io::{Read, Write}, + windmark::response::Response, +}; + +pub fn module(router: &mut windmark::router::Router) { + track_mount(router, "/finger", "Finger-to-Gemini Gateway", |context| { + success( + &format!( + r"# Finger-to-Gemini Gateway + +To use this gateway, simply append the address of your target resource to the end of the current route, minus the protocol. Routed paths are supported! + +To visit my personal Finger server, <finger://fuwn.me>, you would visit <gemini://fuwn.me/finger/fuwn.me>. + +=> /finger/fuwn.me Try it!" + ), + &context, + ) + }); + track_mount( + router, + "/finger/*uri", + "-Finger-to-Gemini Gateway Router", + |context| { + if let Some(uri) = context.parameters.get("uri") { + let path; + let url = url::Url::parse({ + let mut parts = uri.split("/"); + let host = parts.next().unwrap(); + + path = parts.collect::<Vec<&str>>().join("/"); + + &if !host.contains(":") { + format!("{}:79", host) + } else { + host.to_string() + } + }) + .unwrap(); + + let mut stream = std::net::TcpStream::connect(url.to_string()).unwrap(); + let mut buffer = [0; 1024]; + + stream.write_all(format!("{path}\n").as_bytes()).unwrap(); + + let mut response = String::new(); + + loop { + let bytes_read = stream.read(&mut buffer).unwrap(); + + if bytes_read == 0 { + break; + } + + #[allow(unsafe_code)] + response.push_str(unsafe { + std::str::from_utf8_unchecked(&buffer[..bytes_read]) + }); + } + + Response::success(response) + } else { + Response::bad_request("Invalid URI") + } + }, + ); +} |