aboutsummaryrefslogtreecommitdiff
path: root/src/modules/finger.rs
blob: c61cfbebdeaa0869dc4c69e8191c28b80ce6988b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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")
      }
    },
  );
}