From eb9c2898d041b1e16c903d3f66605afd01362162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 10 May 2020 22:19:52 +0200 Subject: [PATCH] better handling of HEAD, add robots.txt --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/{ => embed}/favicon.ico | Bin src/embed/robots.txt | 2 ++ src/main.rs | 69 ++++++++++++++++++++---------------- 5 files changed, 43 insertions(+), 32 deletions(-) rename src/{ => embed}/favicon.ico (100%) create mode 100644 src/embed/robots.txt diff --git a/Cargo.lock b/Cargo.lock index d63b7da..9bfeefb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,7 +735,7 @@ dependencies = [ [[package]] name = "postit" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 804918a..f1f22cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postit" -version = "0.1.0" +version = "0.2.0" authors = ["Ondřej Hruška "] edition = "2018" publish = false diff --git a/src/favicon.ico b/src/embed/favicon.ico similarity index 100% rename from src/favicon.ico rename to src/embed/favicon.ico diff --git a/src/embed/robots.txt b/src/embed/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/src/embed/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/src/main.rs b/src/main.rs index 116208e..096547f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,8 @@ const GET_EXPIRY: &str = "expire"; /// GET param to pass secret token (as a substitute for header) const GET_SECRET: &str = "secret"; -const FAVICON: &[u8] = include_bytes!("favicon.ico"); +const FAVICON: &[u8] = include_bytes!("embed/favicon.ico"); +const ROBOTS: &[u8] = include_bytes!("embed/robots.txt"); /// Post ID (represented as a 16-digit hex string) type PostId = u64; @@ -95,15 +96,23 @@ fn main() -> anyhow::Result<()> { info!("{} {}", method, req.raw_url()); - if req.url() == "/favicon.ico" { - return decorate_response(Response::from_data("image/vnd.microsoft.icon", FAVICON)); + if method == "GET" || method == "HEAD" { + if req.url() == "/favicon.ico" { + return decorate_response(Response::from_data("image/vnd.microsoft.icon", FAVICON) + .with_public_cache(86400 * 7)); + } + + if req.url() == "/robots.txt" { + return decorate_response(Response::from_data("text/plain", ROBOTS) + .with_public_cache(86400)); + } } store_w.gc_expired_posts_if_needed(); let resp = match method { "POST" | "PUT" => store_w.serve_post_put(req), - "GET" | "HEAD" => store_w.serve_get_head(req), + "GET" | "HEAD" => store_w.serve_get(req), "DELETE" => store_w.serve_delete(req), _ => rouille::Response::empty_400(), }; @@ -330,8 +339,8 @@ impl Repository { resp.with_additional_header(HDR_EXPIRY, post.time_remains().as_secs().to_string()) } - /// Serve a GET or HEAD request - fn serve_get_head(&mut self, req: &Request) -> Response { + /// Serve a GET request + fn serve_get(&mut self, req: &Request) -> Response { let post_id = match self.request_to_post_id(req, false) { Ok(Some(pid)) => pid, Ok(None) => return error_with_text(400, "File ID required."), @@ -343,36 +352,36 @@ impl Repository { warn!("GET of expired post!"); Response::empty_404() } else { - let data = self.data.get(&post.hash); - if data.is_none() { - error!("No matching data!"); - return error_with_text(500, "File data lost."); - } + let data = match self.data.get(&post.hash) { + Some((_uses, data)) => data, + None => { + error!("No matching data!"); + return error_with_text(500, "File data lost."); + } + }; let seconds_remains = post.expires.signed_duration_since(Utc::now()) .num_seconds(); + let headers = vec![ + ( + "Content-Type".into(), + format!("{}; charset=utf8", post.mime).into(), + ), + ( + "Cache-Control".into(), + format!("public, max-age={}", seconds_remains).into() + ), + ( + HDR_EXPIRY.into(), + seconds_remains.to_string().into() + ) + ]; + Response { status_code: 200, - headers: vec![ - ( - "Content-Type".into(), - format!("{}; charset=utf8", post.mime).into(), - ), - ( - "Cache-Control".into(), - format!("public, max-age={}", seconds_remains).into() - ), - ( - HDR_EXPIRY.into(), - seconds_remains.to_string().into() - ) - ], - data: if req.method() == "HEAD" { - ResponseBody::empty() - } else { - ResponseBody::from_data(data.unwrap().1.clone()) - }, + headers, + data: ResponseBody::from_data(data.clone()), upgrade: None, } }