Skip to content

Commit e2a0907

Browse files
committed
Merge pull request #1 from conduit-rust/more-headers
Add some more headers for conditional-get
2 parents 39af37f + acfb229 commit e2a0907

File tree

1 file changed

+67
-10
lines changed

1 file changed

+67
-10
lines changed

src/conduit-static.rs

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
extern crate mime = "mime-types";
21
extern crate conduit;
2+
extern crate mime = "mime-types";
3+
extern crate time;
34

45
use std::fmt::Show;
56
use std::collections::HashMap;
@@ -36,10 +37,28 @@ impl Handler for Static {
3637
}
3738

3839
let mime = self.types.mime_for_path(&path);
39-
let file = try!(File::open(&path).map_err(|e| box e as Box<Show>));
40+
let mut file = match File::open(&path) {
41+
Ok(f) => f,
42+
Err(..) => {
43+
return Ok(Response {
44+
status: (404, "Not Found"),
45+
headers: HashMap::new(),
46+
body: box NullReader,
47+
})
48+
}
49+
};
50+
let stat = try!(file.stat().map_err(|e| box e as Box<Show>));
51+
let ts = time::Timespec {
52+
sec: (stat.modified as i64) / 1000,
53+
nsec: ((stat.modified as i32) % 1000) * 1000
54+
};
55+
let tm = time::at(ts).to_utc();
4056

4157
let mut headers = HashMap::new();
42-
headers.insert("Content-Type".to_str(), vec!(mime.to_str()));
58+
headers.insert("Content-Type".to_str(), vec![mime.to_str()]);
59+
headers.insert("Content-Length".to_str(), vec![stat.size.to_str()]);
60+
headers.insert("Last-Modified".to_str(),
61+
vec![tm.strftime("%a, %d %b %Y %T GMT")]);
4362

4463
Ok(Response {
4564
status: (200, "OK"),
@@ -52,27 +71,65 @@ impl Handler for Static {
5271
#[cfg(test)]
5372
mod tests {
5473
extern crate test = "conduit-test";
74+
75+
use std::io::{fs, File, TempDir, UserRWX};
76+
5577
use conduit;
5678
use conduit::Handler;
5779
use Static;
5880

5981
#[test]
6082
fn test_static() {
61-
let root = Path::new(file!()).dir_path().dir_path();
62-
let handler = Static::new(root);
83+
let td = TempDir::new("conduit-static").unwrap();
84+
let root = td.path();
85+
let handler = Static::new(root.clone());
86+
File::create(&root.join("Cargo.toml")).write(b"[package]").unwrap();
6387
let mut req = test::MockRequest::new(conduit::Get, "/Cargo.toml");
6488
let mut res = handler.call(&mut req).ok().expect("No response");
6589
let body = res.body.read_to_str().ok().expect("No body");
66-
assert!(body.as_slice().contains("[package]"), "The Cargo.toml was provided");
67-
assert_eq!(res.headers.find_equiv(&"Content-Type").expect("No content-type"), &vec!("text/plain".to_str()));
90+
assert_eq!(body.as_slice(), "[package]");
91+
assert_eq!(res.headers.find_equiv(&"Content-Type"),
92+
Some(&vec!("text/plain".to_str())));
93+
assert_eq!(res.headers.find_equiv(&"Content-Length"),
94+
Some(&vec!["9".to_str()]));
6895
}
6996

7097
#[test]
7198
fn test_mime_types() {
72-
let root = Path::new(file!()).dir_path().dir_path();
73-
let handler = Static::new(root);
99+
let td = TempDir::new("conduit-static").unwrap();
100+
let root = td.path();
101+
fs::mkdir(&root.join("src"), UserRWX).unwrap();
102+
File::create(&root.join("src/fixture.css")).unwrap();
103+
104+
let handler = Static::new(root.clone());
74105
let mut req = test::MockRequest::new(conduit::Get, "/src/fixture.css");
75106
let res = handler.call(&mut req).ok().expect("No response");
76-
assert_eq!(res.headers.find_equiv(&"Content-Type").expect("No content-type"), &vec!("text/css".to_str()));
107+
assert_eq!(res.headers.find_equiv(&"Content-Type"),
108+
Some(&vec!("text/css".to_str())));
109+
assert_eq!(res.headers.find_equiv(&"Content-Length"),
110+
Some(&vec!["0".to_str()]));
111+
}
112+
113+
#[test]
114+
fn test_missing() {
115+
let td = TempDir::new("conduit-static").unwrap();
116+
let root = td.path();
117+
118+
let handler = Static::new(root.clone());
119+
let mut req = test::MockRequest::new(conduit::Get, "/nope");
120+
let res = handler.call(&mut req).ok().expect("No response");
121+
assert_eq!(res.status.val0(), 404);
122+
}
123+
124+
#[test]
125+
fn last_modified() {
126+
let td = TempDir::new("conduit-static").unwrap();
127+
let root = td.path();
128+
File::create(&root.join("test")).unwrap();
129+
let handler = Static::new(root.clone());
130+
let mut req = test::MockRequest::new(conduit::Get, "/test");
131+
let res = handler.call(&mut req).ok().expect("No response");
132+
assert_eq!(res.status.val0(), 200);
133+
assert!(res.headers.find_equiv(&"Last-Modified").is_some());
77134
}
78135
}

0 commit comments

Comments
 (0)