~garritfra/public-inbox

taurus: Fallback to index.gmi, more modular code v1 NEEDS REVISION

Alexey Yerin: 1
 Fallback to index.gmi, more modular code

 1 files changed, 33 insertions(+), 26 deletions(-)
> I think the more "gemini-like" approach would be to return a 31
> (permanent redirect) with the location of <Requested Directory>/index.gmi.
I also think that's better. When I was wrinting this, I tried to mimic
HTTP servers whose return `index.html` on `/` without actually
redirecting anywhere.
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~garritfra/public-inbox/patches/14834/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH taurus] Fallback to index.gmi, more modular code Export this patch

Now it user tries to request a page without a path, server will try to
send index.gmi instead of throwing a 51.
Also, some repeated parts are now their own funtions which makes code
much simpler.

---
 src/main.rs | 59 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index d3557b1..0d1c9b0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,7 @@ mod gemini;

use native_tls::{Identity, TlsAcceptor, TlsStream};
use std::fs::File;
use std::io;
use std::io::Read;
use std::io::Write;
use std::net::TcpListener;
@@ -39,7 +40,34 @@ fn main() {
                    Err(e) => println!("Can't handle stream: {}", e),
                });
            }
            Err(_e) => println!("Error: {}", _e),
            Err(err) => println!("Error: {}", err),
        }
    }
}

/// Helper function to read a file into Vec
fn read_file(file_path: &str) -> Result<Vec<u8>, io::Error> {
    let mut file = File::open(file_path)?;
    let mut buf = Vec::new();

    file.read_to_end(&mut buf)?;

    Ok(buf)
}

/// Send file as a response
fn send_file(path: &str, response: &mut gemini::GeminiResonse) {
    match read_file(path) {
        Ok(buf) => {
            response.body = Some(buf);
        }
        Err(err) => {
            // Cannot read file or it doesn't exist

            println!("Error ({}): {}", path, err);

            response.status = [b'5', b'1'];
            response.meta = format!("Resource not found: {}", path).into();
        }
    }
}
@@ -60,31 +88,10 @@ fn handle_client(mut stream: TlsStream<TcpStream>) {
    let request = gemini::GeminiRequest::from_string(&raw_request).unwrap();
    let mut response = gemini::GeminiResonse::new();

    match request.file_path() {
        Some(file_path) => {
            println!("Reading {}", file_path);

            match File::open(file_path) {
                Ok(mut file) => {
                    let mut body_buf = Vec::new();
                    if let Err(e) = file.read_to_end(&mut body_buf) {
                        println!("Could not read file {}", e);
                    }

                    response.body = Some(body_buf);
                }
                Err(e) => {
                    let file_path = request.file_path().unwrap_or("");
                    println!("Error ({}): {}", file_path, e);
                    response.status = [b'5', b'1'];
                    response.meta = format!("Resource not found: {}", file_path).into();
                }
            }
        }
        None => {
            println!("No file found in request");
            response.status = [b'5', b'1']
        }
    if let Some(path) = request.file_path() {
        send_file(path, &mut response);
    } else {
        send_file("index.gmi", &mut response);
    }

    if let Err(e) = stream.write(&response.build()) {
-- 
2.29.2