diff --git a/src/web/error.rs b/src/web/error.rs index f7ed1857b..09080070d 100644 --- a/src/web/error.rs +++ b/src/web/error.rs @@ -4,6 +4,7 @@ use iron::Handler; use iron::status; use web::page::Page; use std::fmt; +use time; #[derive(Debug, Copy, Clone)] pub enum Nope { @@ -48,7 +49,21 @@ impl Handler for Nope { Nope::NoResults => { use params::{Params, Value}; let params = req.get::().unwrap(); - if let Some(&Value::String(ref query)) = params.find(&["query"]) { + + if req.url.path().join("/").ends_with(".json") { + use iron::status; + use iron::headers::{Expires, HttpDate, CacheControl, CacheDirective, ContentType, + AccessControlAllowOrigin}; + + let mut resp = Response::with((status::Ok, "[]")); + resp.headers.set(ContentType("application/json".parse().unwrap())); + resp.headers.set(Expires(HttpDate(time::now()))); + resp.headers.set(CacheControl(vec![CacheDirective::NoCache, + CacheDirective::NoStore, + CacheDirective::MustRevalidate])); + resp.headers.set(AccessControlAllowOrigin::Any); + Ok(resp) + } else if let Some(&Value::String(ref query)) = params.find(&["query"]) { // this used to be a search Page::new(Vec::::new()) .set_status(status::NotFound) diff --git a/src/web/mod.rs b/src/web/mod.rs index 20f282542..0d809d3b6 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -125,6 +125,9 @@ impl CratesfyiHandler { router.get("/releases/search", releases::search_handler, "releases_search"); + router.get("/releases/search.json", + releases::search_handler, + "releases_search_json"); router.get("/releases/queue", releases::build_queue_handler, "releases_queue"); diff --git a/src/web/releases.rs b/src/web/releases.rs index 0d260ffa9..babea2318 100644 --- a/src/web/releases.rs +++ b/src/web/releases.rs @@ -477,10 +477,25 @@ pub fn search_handler(req: &mut Request) -> IronResult { .ok_or(IronError::new(Nope::NoResults, status::NotFound)) .and_then(|(_, results)| { // FIXME: There is no pagination - Page::new(results) - .set("search_query", &query) - .title(&format!("Search results for '{}'", query)) - .to_resp("releases") + if req.url.path().join("/").ends_with(".json") { + use iron::status; + use iron::headers::{Expires, HttpDate, CacheControl, CacheDirective, ContentType, + AccessControlAllowOrigin}; + + let mut resp = Response::with((status::Ok, results.to_json().to_string())); + resp.headers.set(ContentType("application/json".parse().unwrap())); + resp.headers.set(Expires(HttpDate(time::now()))); + resp.headers.set(CacheControl(vec![CacheDirective::NoCache, + CacheDirective::NoStore, + CacheDirective::MustRevalidate])); + resp.headers.set(AccessControlAllowOrigin::Any); + Ok(resp) + } else { + Page::new(results) + .set("search_query", &query) + .title(&format!("Search results for '{}'", query)) + .to_resp("releases") + } }) } else { Err(IronError::new(Nope::NoResults, status::NotFound))