From 5b7868080f8f537908369671365ed4fa91925e2a Mon Sep 17 00:00:00 2001 From: Jordan Johnson-Doyle Date: Thu, 21 Feb 2019 16:41:39 +0000 Subject: [PATCH] Prevent cloning paste on show where not necessary --- Cargo.lock | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- Cargo.toml | 3 ++- src/io.rs | 25 +++++++++++++++++-------- src/main.rs | 31 ++++++++++++++++++++----------- 4 files changed, 82 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a6da7e..f0ba421 100644 --- a/Cargo.lock +++ a/Cargo.lock @@ -7,19 +7,20 @@ [[package]] name = "askama" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "askama_derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "askama_shared 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "askama_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "askama_derive" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "askama_shared 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -27,10 +28,17 @@ ] [[package]] +name = "askama_escape" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "askama_shared" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", @@ -63,10 +71,11 @@ name = "bin" version = "1.0.2" dependencies = [ - "askama 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "gpw 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", @@ -75,7 +84,7 @@ [[package]] name = "bincode" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -210,6 +219,11 @@ [[package]] name = "httparse" version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "humansize" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -432,6 +446,14 @@ dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "owning_ref" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -683,7 +705,7 @@ "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -755,11 +777,13 @@ [[package]] name = "smallvec" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "state" @@ -781,7 +805,7 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bincode 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bincode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -851,21 +875,13 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-xid" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unreachable" -version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "url" @@ -880,11 +896,6 @@ [[package]] name = "version_check" version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -952,13 +963,14 @@ [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum askama 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eed81479263c8753e06f4981f5a313b3fe6cbff30c3ff8d9ae15ef0c72d93fb5" -"checksum askama_derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46580c08e5520afadc6e9064759e15fc743489a4db78f9c751113e3d32a1e083" -"checksum askama_shared 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "64509fd5c2fa767fa7ea973b732c61f0b8d30d1adf084e5164523e51a5e35d71" +"checksum askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc2a4b6d7f812d2b13d251ae792caecebd635d6401761162d4b71d5ebe1a010" +"checksum askama_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ee2fff0f22ad5d215cace1227cd036c28e81e26206763bb837b6d0e766c87d" +"checksum askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0de942230b5beedaa9e1d64df5b76fa1c97002e4c7982897be899cccf40621d" +"checksum askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6dfa6b6d254fd066a8bbed9a8f913123e3f701db89216ad4f0aff04ad87718c" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bincode 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58470ad6460f0b0e89b0df5f17b8bd77ebae26af69dca0bd9ddc8b9e38abb2ff" +"checksum bincode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3efe0b4c8eaeed8600549c29f538a6a11bf422858d0ed435b1d70ec4ab101190" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" @@ -977,6 +989,7 @@ "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum gpw 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f0289c2eaf649918996197a6dde734d62414178a67a23f89f08610c6e8564e" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" @@ -1005,6 +1018,7 @@ "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" "checksum onig 4.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a646989adad8a19f49be2090374712931c3a59835cb5277b4530f48b417f26e7" "checksum onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum packed_simd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" "checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25" "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" @@ -1041,7 +1055,8 @@ "checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" "checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" -"checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" +"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" "checksum syntect 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e02dd9df97a68a2d005ace28ff24c610abfc3ce17afcfdb22a077645dabb599a" @@ -1054,10 +1069,8 @@ "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index ce12938..60c3c47 100644 --- a/Cargo.toml +++ a/Cargo.toml @@ -8,9 +8,10 @@ edition = "2018" [dependencies] +owning_ref = "0.4" linked-hash-map = "0.5" rocket = { version = "0.4", default-features = false } -askama = "0.7" +askama = "0.8" lazy_static = "1.2" rand = { version = "0.6", features = ["nightly"] } gpw = "0.1" diff --git a/src/io.rs b/src/io.rs index 55734a5..8d74d6e 100644 --- a/src/io.rs +++ a/src/io.rs @@ -1,5 +1,6 @@ extern crate gpw; extern crate linked_hash_map; +extern crate owning_ref; extern crate rand; use rand::distributions::Alphanumeric; @@ -7,9 +8,11 @@ use linked_hash_map::LinkedHashMap; +use owning_ref::RwLockReadGuardRef; + use std::cell::RefCell; use std::env; -use std::sync::RwLock; +use std::sync::{PoisonError, RwLock}; lazy_static! { static ref ENTRIES: RwLock> = RwLock::new(LinkedHashMap::new()); @@ -25,12 +28,12 @@ /// /// During the purge, `ENTRIES` is locked and the current thread will block. fn purge_old() { - let entries_len = ENTRIES.read().unwrap_or_else(|p| p.into_inner()).len(); + let entries_len = ENTRIES.read().unwrap_or_else(PoisonError::into_inner).len(); if entries_len > *BUFFER_SIZE { let to_remove = entries_len - *BUFFER_SIZE; - let mut entries = ENTRIES.write().unwrap_or_else(|p| p.into_inner()); + let mut entries = ENTRIES.write().unwrap_or_else(PoisonError::into_inner); for _ in 0..to_remove { entries.pop_front(); @@ -54,17 +57,19 @@ purge_old(); ENTRIES .write() - .unwrap_or_else(|p| p.into_inner()) + .unwrap_or_else(PoisonError::into_inner) .insert(id, content); } /// Get a paste by id. /// /// Returns `None` if the paste doesn't exist. -pub fn get_paste(id: &str) -> Option { - ENTRIES - .read() - .unwrap_or_else(|p| p.into_inner()) - .get(id) - .cloned() +pub fn get_paste(id: &str) -> Option, String>> { + let or = RwLockReadGuardRef::new(ENTRIES.read().unwrap_or_else(PoisonError::into_inner)); + + if or.contains_key(id) { + Some(or.map(|x| x.get(id).unwrap())) + } else { + None + } } diff --git a/src/main.rs b/src/main.rs index 47e33d8..aa6a480 100644 --- a/src/main.rs +++ a/src/main.rs @@ -17,7 +17,7 @@ use io::{generate_id, get_paste, store_paste}; use params::{HostHeader, IsPlaintextRequest}; -use askama::{MarkupDisplay, Template}; +use askama::{Html as AskamaHtml, MarkupDisplay, Template}; use rocket::http::{ContentType, Status}; use rocket::request::Form; @@ -25,6 +25,7 @@ use rocket::response::Redirect; use rocket::Data; +use std::borrow::Cow; use std::io::Read; /// @@ -39,7 +40,7 @@ fn index() -> Result, Status> { Index .render() - .map(|h| Html(h)) + .map(Html) .map_err(|_| Status::InternalServerError) } @@ -82,8 +83,8 @@ #[derive(Template)] #[template(path = "paste.html")] -struct ShowPaste { - content: MarkupDisplay, +struct ShowPaste<'a> { + content: MarkupDisplay>, } #[get("/")] @@ -94,22 +95,24 @@ // get() returns a read-only lock, we're not going to be writing to this key // again so we can hold this for as long as we want - let entry = get_paste(key).ok_or_else(|| Status::NotFound)?; + let entry = &*get_paste(key).ok_or_else(|| Status::NotFound)?; if *plaintext { - Ok(Content(ContentType::Plain, entry)) + Ok(Content(ContentType::Plain, entry.to_string())) } else { let content = match ext { - None => MarkupDisplay::Unsafe(entry), - Some(extension) => highlight(&entry, extension) - .map(|h| MarkupDisplay::Safe(h)) - .ok_or_else(|| Status::NotFound)?, + Some(extension) => match highlight(&entry, extension) { + Some(html) => MarkupDisplay::new_safe(Cow::Owned(html), AskamaHtml), + None => return Err(Status::NotFound), + }, + None => MarkupDisplay::new_unsafe(Cow::Borrowed(entry), AskamaHtml), }; - ShowPaste { content } - .render() - .map(|html| Content(ContentType::HTML, html)) - .map_err(|_| Status::InternalServerError) + let template = ShowPaste { content }; + match template.render() { + Ok(html) => Ok(Content(ContentType::HTML, html)), + Err(_) => Err(Status::InternalServerError), + } } } -- rgit 0.1.3