Repositories

grarr

(mirrored on github)

Wim Looman <wim@nemo157.com>
774648 Disable caching during development
Wim Looman committed at 2016-02-19 14:22:11

Modified src/handler/avatar.rs

@@ -1,9 +1,10 @@
use std::borrow::Cow;
use std::time::Duration;
use gravatar::{ self, Gravatar };
use hyper;
use hyper::client::Client;
use iron::IronResult;
use iron::headers::{ EntityTag, ETag, CacheControl, CacheDirective, Vary, IfNoneMatch, ContentType };
use iron::headers::{ EntityTag, ContentType };
use iron::middleware::Handler;
use iron::request::Request;
use iron::response::Response;
@@ -12,11 +13,9 @@ use router::Router;
use iron::status;
use iron::method::Method;
use lru_time_cache::LruCache;
use time::Duration;
use time::Duration as Duration2;
use std::sync::Mutex;
use iron::modifiers::Header;
use unicase::UniCase;
use super::utils::{ sha1, File };
use super::utils::{ self, sha1, File, CacheMatches };
pub struct Avatars {
enable_gravatar: bool,
@@ -35,7 +34,7 @@ pub struct Options {
pub enable_gravatar: bool,
pub enable_cache: bool,
pub cache_capacity: usize,
pub cache_time_to_live: Duration,
pub cache_time_to_live: Duration2,
}
impl Avatars {
@@ -99,20 +98,9 @@ impl Handler for Avatars {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
let user = req.extensions.get::<Router>().unwrap().find("user").unwrap();
let File(mime, entity_tag, buffer) = self.find_image(user);
let cache_headers = (
Header(CacheControl(vec![
CacheDirective::Public,
CacheDirective::MaxAge(86400),
])),
Header(ETag(entity_tag.clone())),
Header(Vary::Items(vec![
UniCase("accept-encoding".to_owned()),
])),
);
if let Some(&IfNoneMatch::Items(ref items)) = req.headers.get() {
if items.len() == 1 && items[0] == entity_tag {
return Ok(Response::with((status::NotModified, cache_headers)));
}
let cache_headers = utils::cache_headers_for(&entity_tag, Duration::from_secs(86400));
if req.cache_matches(&entity_tag) {
return Ok(Response::with((status::NotModified, cache_headers)));
}
Ok(Response::with((status::Ok, mime, cache_headers, buffer.as_ref())))
}

Modified src/handler/html.rs

@@ -1,11 +1,11 @@
use iron::headers::{ EntityTag, ETag, CacheControl, CacheDirective, Vary, IfNoneMatch };
use std::time::Duration;
use iron::headers::EntityTag;
use iron::modifier::Modifier;
use iron::modifiers::Header;
use iron::request::Request;
use iron::response::Response;
use iron::{ status, IronResult };
use maud::RenderOnce;
use unicase::UniCase;
use super::utils::{ self, CacheMatches };
pub struct Html<'a, 'b: 'a, 'c: 'b, R: RenderOnce> {
pub req: &'a Request<'b, 'c>,
@@ -28,22 +28,11 @@ impl<'a, 'b, 'c, R: RenderOnce> Into<IronResult<Response>> for Html<'a, 'b, 'c,
impl<'a, 'b, 'c, R: RenderOnce> Modifier<Response> for Html<'a, 'b, 'c, R> {
fn modify(self, response: &mut Response) {
if let Some(ref etag) = self.etag {
let cache_headers = (
Header(CacheControl(vec![
CacheDirective::Public,
CacheDirective::MaxAge(0),
])),
Header(ETag(etag.clone())),
Header(Vary::Items(vec![
UniCase("accept-encoding".to_owned()),
])),
);
let cache_headers = utils::cache_headers_for(&etag, Duration::from_secs(0));
cache_headers.modify(response);
if let Some(&IfNoneMatch::Items(ref items)) = self.req.headers.get() {
if items.len() == 1 && items[0] == *etag {
status::NotModified.modify(response);
return;
}
if self.req.cache_matches(etag) {
status::NotModified.modify(response);
return;
}
}
let buffer = to_string!(^self.render);

Modified src/handler/statics.rs

@@ -1,4 +1,5 @@
use std::borrow::Cow;
use std::time::Duration;
use iron::IronResult;
use iron::middleware::Handler;
use iron::request::Request;
@@ -11,10 +12,7 @@ use std::sync::Mutex;
use error::Error;
use std::collections::HashMap;
use std::path::{ Path, PathBuf };
use iron::modifiers::Header;
use iron::headers::{ ETag, CacheControl, CacheDirective, Vary, IfNoneMatch };
use unicase::UniCase;
use super::utils::File;
use super::utils::{ self, File, CacheMatches };
#[derive(Debug)]
pub struct Static {
@@ -54,20 +52,9 @@ impl Handler for Static {
let router = itry!(req.extensions.get::<Router>().ok_or(Error::MissingExtension), status::InternalServerError);
let path = Path::new(itry!(router.find("path").ok_or(Error::MissingPathComponent), status::InternalServerError));
let File(mime, entity_tag, buffer) = itry!(self.find_file(path).ok_or(Error::String("Static file not found")), status::NotFound);
let cache_headers = (
Header(CacheControl(vec![
CacheDirective::Public,
CacheDirective::MaxAge(86400),
])),
Header(ETag(entity_tag.clone())),
Header(Vary::Items(vec![
UniCase("accept-encoding".to_owned()),
])),
);
if let Some(&IfNoneMatch::Items(ref items)) = req.headers.get() {
if items.len() == 1 && items[0] == entity_tag {
return Ok(Response::with((status::NotModified, cache_headers)));
}
let cache_headers = utils::cache_headers_for(&entity_tag, Duration::from_secs(86400));
if req.cache_matches(&entity_tag) {
return Ok(Response::with((status::NotModified, cache_headers)));
}
Ok(Response::with((status::Ok, mime, cache_headers, &*buffer)))
}

Modified src/handler/utils.rs

@@ -1,11 +1,13 @@
use std::fmt;
use std::time::Duration;
use std::borrow::Cow;
use std::path::Path;
use crypto::digest::Digest;
use crypto::sha1::Sha1;
use mime::Mime;
use iron::headers::{ EntityTag };
use iron::headers::EntityTag;
use iron::request::Request;
#[macro_export]
macro_rules! file {
@@ -61,3 +63,61 @@ pub fn sha1<T: AsRef<[u8]>>(file: T) -> String {
hasher.input(file.as_ref());
hasher.result_str()
}
pub trait CacheMatches {
fn cache_matches(&self, etag: &EntityTag) -> bool;
}
// In debug mode assume the etag never matches so we
// don't have to bump version numbers for dynamic content
// (hacky detection, see https://users.rust-lang.org/t/1098)
#[cfg(debug_assertions)]
impl<'a, 'b> CacheMatches for Request<'a, 'b> {
fn cache_matches(&self, _etag: &EntityTag) -> bool {
false
}
}
#[cfg(not(debug_assertions))]
impl<'a, 'b> CacheMatches for Request<'a, 'b> {
fn cache_matches(&self, etag: &EntityTag) -> bool {
use iron::headers::IfNoneMatch;
if let Some(&IfNoneMatch::Items(ref items)) = self.headers.get() {
if items.len() == 1 && items[0] == *etag {
return true;
}
}
false
}
}
#[cfg(debug_assertions)] use iron::modifiers::Header;
#[cfg(debug_assertions)] use iron::headers::Vary;
#[cfg(debug_assertions)] use unicase::UniCase;
// Should return () once https://github.com/reem/rust-modifier/pull/19 is merged
#[cfg(debug_assertions)]
pub fn cache_headers_for(_entity_tag: &EntityTag, _duration: Duration) -> Header<Vary> {
Header(Vary::Items(vec![
UniCase("accept-encoding".to_owned()),
]))
}
#[cfg(not(debug_assertions))] use iron::modifiers::Header;
#[cfg(not(debug_assertions))] use iron::headers::{ ETag, CacheControl, CacheDirective, Vary };
#[cfg(not(debug_assertions))] use unicase::UniCase;
// Where's my abstract return types....
#[cfg(not(debug_assertions))]
pub fn cache_headers_for(entity_tag: &EntityTag, duration: Duration)
-> (Header<CacheControl>, Header<ETag>, Header<Vary>)
{
(
Header(CacheControl(vec![
CacheDirective::Public,
CacheDirective::MaxAge(duration.as_secs() as u32),
])),
Header(ETag(entity_tag.clone())),
Header(Vary::Items(vec![
UniCase("accept-encoding".to_owned()),
])),
)
}