update readme, default configuration path

This commit is contained in:
Jan Wolff 2020-05-17 19:46:48 +02:00
parent 72c1e3c813
commit faab34d44f
4 changed files with 35 additions and 17 deletions

View file

@ -7,29 +7,34 @@ Features
-------- --------
This can't do much right now besides hosting some static files. In fact, the This can't do much right now besides hosting some static files. In fact, the
feature set happens to be limited to what I need to host my own gemini page. feature set happens to be limited to what I need to host my own Gemini page.
Coincidence? Coincidence?
More is to come however. Specifically I'd want to add CGI support. And maybe More is to come however. Specifically I'd want to add CGI support. And maybe
reverse proxy support as well, depending on how much stuff I'll be hosting over reverse proxy support as well, depending on how much stuff I'll be hosting over
Gemini. Gemini.
Platform Support
----------------
This currently only works on UNIX platforms as `setuid` and `setgid` system
calls are used to drop the privilege level after initialization. Currently
there is no way to disable this. Of course, Gemini's default port (1965) can be
opened in user-mode, but not changing the user after startup would retain read
permissions to the private key.
Starting Starting
-------- --------
Right now every relevant option needs to be given through command line Sheldon Director look for a config file in `/etc/sheldond.conf`. If you want to
parameters. Though handling of a configuration file is a feature I'll add change this, pass an alternative path on startup like so:
later on.
An example start can look like this: An example start can look like this:
```sh ```sh
sudo ./sheldond -l "[::]:1965" -l "0.0.0.0:1965" -d "klockenschooster.de" -g /var/gemini/ --user gem-data --group gem-data sudo ./sheldond -c ./sheldond.conf
``` ```
This serves the content of the folder `/var/gemini/` over both IPv4 and IPv6 An example config file can be found in this repository in `doc/sheldond.conf`.
on port 1965 on the domain `klockenschooster.de`. After opening the socket and
reading the certificates the server sets its user and group id to the
respective values for `gem-data`.
Why "Sheldon Director"? Why "Sheldon Director"?
----------------------- -----------------------

View file

@ -20,6 +20,10 @@ fn parse_args() -> Option<String> {
loop { loop {
match args.next() { match args.next() {
Some(arg) => { Some(arg) => {
if arg == "-h" || arg == "--help" {
help();
return None;
}
if arg == "-c" || arg == "--config" { if arg == "-c" || arg == "--config" {
let config_fname = args.next().unwrap(); let config_fname = args.next().unwrap();
return Some(config_fname); return Some(config_fname);
@ -29,7 +33,7 @@ fn parse_args() -> Option<String> {
} }
} }
None Some("/etc/sheldond.conf".to_string())
} }
fn parse_config(fname: String) -> server::ServerConfig { fn parse_config(fname: String) -> server::ServerConfig {
@ -38,8 +42,8 @@ fn parse_config(fname: String) -> server::ServerConfig {
let file = match File::open(path) { let file = match File::open(path) {
Ok(file) => BufReader::new(file), Ok(file) => BufReader::new(file),
Err(e) => { Err(_) => {
panic!(e); panic!("could not open config file: {}", fname);
} }
}; };
@ -77,13 +81,13 @@ fn parse_config(fname: String) -> server::ServerConfig {
} }
fn main() { fn main() {
let config = match parse_args() { let config_fname = match parse_args() {
Some(config_fname) => parse_config(config_fname), Some(config_fname) => config_fname,
None => { None => {
help();
return; return;
} }
}; };
let config = parse_config(config_fname);
let server = server::Server::new(&config); let server = server::Server::new(&config);
server.serve(); server.serve();

View file

@ -14,6 +14,7 @@ pub fn get_mime_type(extension: &OsStr) -> &'static str {
match ext_str { match ext_str {
"gmi" => "text/gemini", "gmi" => "text/gemini",
"gemini" => "text/gemini",
"txt" => "text/plain", "txt" => "text/plain",
_ => default_mime_type(), _ => default_mime_type(),
} }

View file

@ -5,7 +5,7 @@ use openssl::ssl::SslStream;
use std::fs::File; use std::fs::File;
use std::io::{copy, BufReader, BufWriter}; use std::io::{copy, BufReader, BufWriter};
use std::net::TcpStream; use std::net::TcpStream;
use std::path::Path; use std::path::{Path, PathBuf};
use url::Url; use url::Url;
fn send_header(stream: &mut SslStream<TcpStream>, header: &response::Header) { fn send_header(stream: &mut SslStream<TcpStream>, header: &response::Header) {
@ -50,6 +50,13 @@ pub fn handle_request(config: &ServerConfig, mut stream: SslStream<TcpStream>) {
handle_response(config, location, &mut stream); handle_response(config, location, &mut stream);
} }
fn gen_path_index(path: &Path) -> PathBuf {
match path.is_dir() {
true => path.join("index.gmi"),
false => PathBuf::from(path),
}
}
fn handle_response(config: &ServerConfig, url: Url, mut stream: &mut SslStream<TcpStream>) { fn handle_response(config: &ServerConfig, url: Url, mut stream: &mut SslStream<TcpStream>) {
if url.scheme() != "gemini" { if url.scheme() != "gemini" {
send_header(&mut stream, &response::permanent_failure()); send_header(&mut stream, &response::permanent_failure());
@ -68,7 +75,8 @@ fn handle_response(config: &ServerConfig, url: Url, mut stream: &mut SslStream<T
return; return;
} }
}; };
let path = config.gem_root.join(rel_path);
let path = gen_path_index(&config.gem_root.join(rel_path));
let file = match File::open(&path) { let file = match File::open(&path) {
Ok(file) => file, Ok(file) => file,