summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorMorgana <Morgana@icolotl.com>2026-10-23 11:30:22 -0500
committerMorgana <Morgana@icolotl.com>2026-10-23 11:30:22 -0500
commit605c96969c20cc472ac68f1701f29d689a99e032 (patch)
tree0be6c11841b7c65333f5433e94627beedef98342 /src/main.rs
parentf941e853103089897127fb22b28cc2e7eb8e556f (diff)
Add comments to code
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs
index c2b4509..b25cc07 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,8 +12,12 @@ use rustls::{
};
fn main() {
- println!("Starting MorGemTS Server...");
+ println!("Starting MorGemRS Server...");
+
+ // Path to Gemini content to be hosted
let root: PathBuf = fs::canonicalize("content").unwrap();
+
+ // Load server certificate chains and private keys
let certs = CertificateDer::pem_file_iter("cert/morgemrs.crt")
.unwrap()
.map(|cert| cert.unwrap())
@@ -25,23 +29,37 @@ fn main() {
.with_single_cert(certs, private_key)
.unwrap(),
);
+
+ // Begin listening for connections
let listener = TcpListener::bind("127.0.0.1:1965").unwrap();
+ println!("Successfully Started!");
for mut tcp_stream in listener.incoming().flatten() {
+ // Connect with TLS
let mut conn = ServerConnection::new(config.clone()).unwrap();
let mut tls_stream = Stream::new(&mut conn, &mut tcp_stream);
- let mut buffer = [0; 1027]; // 1024 URI bytes + 2 CRLF bytes + 1 overflow byte
+ // Gemini URIs can be 1024 bytes long + 2 CRLF bytes + 1 overflow byte == 1027b
+ let mut buffer = [0; 1027];
+
+ // Did we successfully recieve data?
let Ok(n) = tls_stream.read(&mut buffer[..]) else {
let _ = writeln!(tls_stream, "59\r\n");
continue;
};
+
+ // Did we recieve too much content?
if n == 1027 {
let _ = writeln!(tls_stream, "59\r\n");
continue;
}
+
+ // Is the data utf-8?
let Ok(raw_uri) = String::from_utf8(buffer.to_vec()) else {
let _ = writeln!(tls_stream, "59\r\n");
continue;
};
+
+ // Trim nulls and whitespace from buffer
+ // Reject proxy requests
let Some(mut uri) = raw_uri
.trim_end_matches(|c: char| c == char::from(0) || c.is_whitespace())
.strip_prefix("gemini://localhost")
@@ -49,15 +67,21 @@ fn main() {
let _ = writeln!(tls_stream, "53 Proxy Not Supported\r\n");
continue;
};
+
+ // Clean up URI
uri = uri.trim_matches('/');
let Ok(path) = root.join(uri).canonicalize() else {
let _ = writeln!(tls_stream, "51 Not Found\r\n");
continue;
};
+
+ // Prevent access to files not in the route
if !path.starts_with(&root) {
let _ = writeln!(tls_stream, "51 Not Found\rpath\n");
continue;
}
+
+ // All checks passed, serve the content
if path.is_dir() {
serve_dir(&path, uri, &mut tls_stream);
} else if path.is_file() {
@@ -69,11 +93,14 @@ fn main() {
}
fn serve_dir(dir: &Path, uri: &str, tls_stream: &mut Stream<'_, ServerConnection, TcpStream>) {
+ // If the directory has a `index.gem` file, serve that instead.
let index_path = dir.join("index.gem");
if index_path.is_file() {
serve_file(&index_path, tls_stream);
return;
}
+
+ // Produce a list of links to directory contents
let Ok(read_dir) = dir.read_dir() else {
let _ = writeln!(tls_stream, "50 Server Error\r\n");
return;
@@ -84,7 +111,7 @@ fn serve_dir(dir: &Path, uri: &str, tls_stream: &mut Stream<'_, ServerConnection
.flat_map(|f| f.file_name().into_string())
.map(|s| {
if uri.is_empty() {
- format!("=> /{}", s)
+ format!("=> /{}", s) // Prevent leading double slash with empty URI
} else {
format!("=> /{}/{} ", uri, s)
}
@@ -95,6 +122,7 @@ fn serve_dir(dir: &Path, uri: &str, tls_stream: &mut Stream<'_, ServerConnection
}
fn serve_file(file: &Path, tls_stream: &mut Stream<'_, ServerConnection, TcpStream>) {
+ // Serve file contents (naive, assumes gemtext)
let Ok(contents) = fs::read_to_string(file) else {
let _ = writeln!(tls_stream, "50 Server Error\r\n");
return;