diff --git a/README.MD b/README.MD index c981603..164ea11 100644 --- a/README.MD +++ b/README.MD @@ -330,6 +330,64 @@ Displays your MicroBin's version information. Changes the maximum width of the UI from 720 pixels to 1080 pixels. +### --public-path [PUBLIC_PATH] + +Add the given public path prefix to all urls. + +This allows you to host MicroBin behind a reverse proxy on a subpath. +Note that MicroBin itself still expects all routes to be as without this option, and thus is unsuited +if you are running MicroBin directly. + +#### Example Usage (caddy) + +An example of running MicroBin behind the reverse proxy `caddy` on the path `/paste` (using systemd) + +**microbin.service** + +```unit file (systemd) +[Unit] +Description=Micobin Paste + +[Service] +Type=simple +User=microbin +# Path to your binary +ExecStart=/home/microbin/microbin/target/release/microbin +# Set your desired working directory, eg where microbin places its data +WorkingDirectory=/home/pi/bin/micro + +# bind to localhost, as its exposed via Caddy +Environment=MICROBIN_BIND=127.0.0.1 +# bind to a unused port +Environment=MICROBIN_PORT=31333 +# All your other config (change and add as needed) +Environment=MICROBIN_EDITABLE=true +Environment=MICROBIN_HIGHLIGHTSYNTAX=true +Environment=MICROBIN_THREADS=2 +Environment=MICROBIN_FOOTER_TEXT="Bin the bytes" +# Set your **public** url. Eg the one you will later use to access microbin +# Ensure it either starts with http(s):// or with a / +Environment=MICROBIN_PUBLIC_PATH="http://100.127.233.32/paste" + +[Install] +WantedBy=multi-user.target +``` + +**Caddyfile** + +```caddy +example.com { + # Your normal http root + root * /var/www/html + file_server + + # Route all requests to past + handle_path /paste/* { + reverse_proxy http://127.0.0.1:31333 + } +} +``` + ### --no-file-upload -Disables and hides the file upload option in the UI. \ No newline at end of file +Disables and hides the file upload option in the UI. diff --git a/src/args.rs b/src/args.rs index 1472391..e4029d4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,4 +1,7 @@ +use std::convert::Infallible; +use std::fmt; use std::net::IpAddr; +use std::str::FromStr; use clap::Parser; use lazy_static::lazy_static; @@ -48,6 +51,9 @@ pub struct Args { #[clap(long, env="MICROBIN_PURE_HTML")] pub pure_html: bool, + #[clap(long, env="MICROBIN_PUBLIC_PATH", default_value_t = PublicUrl(String::from("")))] + pub public_path: PublicUrl, + #[clap(long, env="MICROBIN_READONLY")] pub readonly: bool, @@ -59,7 +65,24 @@ pub struct Args { #[clap(long, env="MICROBIN_WIDE")] pub wide: bool, - + #[clap(short, long, env="MICROBIN_NO_FILE_UPLOAD")] pub no_file_upload: bool, -} \ No newline at end of file +} + +#[derive(Debug, Clone)] +pub struct PublicUrl(pub String); + +impl fmt::Display for PublicUrl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl FromStr for PublicUrl { + type Err = Infallible; + + fn from_str(s: &str) -> Result { + let uri = s.strip_suffix('/').unwrap_or(s).to_owned(); + Ok(PublicUrl(uri)) + } diff --git a/src/endpoints/create.rs b/src/endpoints/create.rs index 40efa41..7b6ca6d 100644 --- a/src/endpoints/create.rs +++ b/src/endpoints/create.rs @@ -32,7 +32,7 @@ pub async fn create( ) -> Result { if ARGS.readonly { return Ok(HttpResponse::Found() - .append_header(("Location", "/")) + .append_header(("Location", format!("{}/", ARGS.public_path))) .finish()); } @@ -158,6 +158,6 @@ pub async fn create( save_to_file(&pastas); Ok(HttpResponse::Found() - .append_header(("Location", format!("/pasta/{}", to_animal_names(id)))) + .append_header(("Location", format!("{}/pasta/{}", ARGS.public_path, to_animal_names(id)))) .finish()) } diff --git a/src/endpoints/edit.rs b/src/endpoints/edit.rs index f928324..54ef1f6 100644 --- a/src/endpoints/edit.rs +++ b/src/endpoints/edit.rs @@ -28,7 +28,7 @@ pub async fn get_edit(data: web::Data, id: web::Path) -> HttpR if pasta.id == id { if !pasta.editable { return HttpResponse::Found() - .append_header(("Location", "/")) + .append_header(("Location", format!("{}/", ARGS.public_path))) .finish(); } return HttpResponse::Ok().content_type("text/html").body( @@ -55,7 +55,7 @@ pub async fn post_edit( ) -> Result { if ARGS.readonly { return Ok(HttpResponse::Found() - .append_header(("Location", "/")) + .append_header(("Location", format!("{}/", ARGS.public_path))) .finish()); } @@ -85,7 +85,7 @@ pub async fn post_edit( save_to_file(&pastas); return Ok(HttpResponse::Found() - .append_header(("Location", format!("/pasta/{}", pastas[i].id_as_animals()))) + .append_header(("Location", format!("{}/pasta/{}", ARGS.public_path, pastas[i].id_as_animals()))) .finish()); } else { break; diff --git a/src/endpoints/pastalist.rs b/src/endpoints/pastalist.rs index 3e3dec4..e2536e5 100644 --- a/src/endpoints/pastalist.rs +++ b/src/endpoints/pastalist.rs @@ -17,7 +17,7 @@ struct PastaListTemplate<'a> { pub async fn list(data: web::Data) -> HttpResponse { if ARGS.no_listing { return HttpResponse::Found() - .append_header(("Location", "/")) + .append_header(("Location", format!("{}/", ARGS.public_path))) .finish(); } diff --git a/src/endpoints/remove.rs b/src/endpoints/remove.rs index 7b95553..6d552b0 100644 --- a/src/endpoints/remove.rs +++ b/src/endpoints/remove.rs @@ -13,7 +13,7 @@ use std::fs; pub async fn remove(data: web::Data, id: web::Path) -> HttpResponse { if ARGS.readonly { return HttpResponse::Found() - .append_header(("Location", "/")) + .append_header(("Location", format!("{}/", ARGS.public_path))) .finish(); } @@ -39,7 +39,7 @@ pub async fn remove(data: web::Data, id: web::Path) -> HttpRes // remove it from in-memory pasta list pastas.remove(i); return HttpResponse::Found() - .append_header(("Location", "/pastalist")) + .append_header(("Location", format!("{}/pastalist", ARGS.public_path))) .finish(); } } diff --git a/templates/error.html b/templates/error.html index 05f55d5..6e60b7c 100644 --- a/templates/error.html +++ b/templates/error.html @@ -4,7 +4,7 @@ Not Found

- Go Home + Go Home

{% include "footer.html" %} diff --git a/templates/header.html b/templates/header.html index 46bb7dc..bb9c69a 100644 --- a/templates/header.html +++ b/templates/header.html @@ -11,7 +11,7 @@ {% if !args.pure_html %} - + {%- endif %} {% if args.wide %} @@ -50,11 +50,11 @@ {%- endif %} -New Pasta +New Pasta -Pasta List +Pasta List -Help +Help
diff --git a/templates/pasta.html b/templates/pasta.html index 6e069ac..4238a57 100644 --- a/templates/pasta.html +++ b/templates/pasta.html @@ -1,19 +1,19 @@ {% include "header.html" %}
diff --git a/templates/pastalist.html b/templates/pastalist.html index 4de2d2b..c3d15a2 100644 --- a/templates/pastalist.html +++ b/templates/pastalist.html @@ -4,7 +4,7 @@ {% if pastas.is_empty() %}

- No pastas yet. 😔 Create one here. + No pastas yet. 😔 Create one here.


{%- else %} @@ -38,7 +38,7 @@ {% if pasta.pasta_type == "text" && !pasta.private %} - {{pasta.id_as_animals()}} + {{pasta.id_as_animals()}} {{pasta.created_as_string()}} @@ -47,14 +47,14 @@ {{pasta.expiration_as_string()}} - Raw + Raw {% if pasta.file.is_some() %} - File + File {%- endif %} {% if pasta.editable %} - Edit + Edit {%- endif %} - Remove + Remove {%- endif %} @@ -90,7 +90,7 @@ {% if pasta.pasta_type == "url" && !pasta.private %} - {{pasta.id_as_animals()}} + {{pasta.id_as_animals()}} {{pasta.created_as_string()}} @@ -99,11 +99,11 @@ {{pasta.expiration_as_string()}} - Raw + Raw {% if pasta.editable %} - Edit + Edit {%- endif %} - Remove + Remove {%- endif %}