1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::path::{PathBuf, Path};
use std::sync::Arc;
use std::net::{SocketAddr, IpAddr};
use httparse::Header;
use pages;
use tk_http::server::{Dispatcher, Error, Head, HeaderIter};
use pages::{Response};
pub struct HttpBin {
prefix: Arc<PathBuf>,
}
pub struct HttpBinDispatcher {
addr: SocketAddr,
prefix: Arc<PathBuf>,
}
pub struct Request<'a> {
addr: SocketAddr,
head: &'a Head<'a>,
prefix: &'a Arc<PathBuf>,
suffix: &'a Path,
}
impl<S: 'static> Dispatcher<S> for HttpBinDispatcher {
type Codec = Response<S>;
fn headers_received(&mut self, headers: &Head)
-> Result<Self::Codec, Error>
{
let path = headers.path()
.and_then(|p| Path::new(p).strip_prefix(&*self.prefix).ok());
let path = match path {
Some(p) => p,
None => {
return Ok(pages::not_found::serve(Request {
addr: self.addr,
head: headers,
prefix: &self.prefix,
suffix: Path::new("--not_found--"),
}));
}
};
let mut path_iter = Path::new(&path).iter();
let first_part = path_iter.next()
.and_then(|x| x.to_str())
.unwrap_or("");
let req = Request {
addr: self.addr,
head: headers,
prefix: &self.prefix,
suffix: path_iter.as_path(),
};
match first_part {
"" => Ok(pages::index::serve(req)),
"ip" => Ok(pages::ip::serve(req)),
"user-agent" => Ok(pages::user_agent::serve(req)),
"headers" => Ok(pages::headers::serve(req)),
"stripped-headers" => Ok(pages::headers::serve_stripped(req)),
"encoding" => Ok(pages::utf8::serve(req)),
"status" => Ok(pages::status::serve(req)),
_ => Ok(pages::not_found::serve(req)),
}
}
}
impl HttpBin {
pub fn new() -> HttpBin {
HttpBin {
prefix: Arc::new(PathBuf::from("/")),
}
}
pub fn new_at(path: &Path) -> HttpBin {
assert!(path.is_absolute());
HttpBin {
prefix: Arc::new(path.to_path_buf()),
}
}
pub fn instantiate(&self, addr: SocketAddr) -> HttpBinDispatcher {
HttpBinDispatcher {
addr: addr,
prefix: self.prefix.clone()
}
}
}
impl<'a> Request<'a> {
pub fn prefix(&self) -> &Arc<PathBuf> {
self.prefix
}
pub fn ip(&self) -> IpAddr {
self.addr.ip()
}
pub fn headers(&self) -> ::std::slice::Iter<Header> {
self.head.all_headers().iter()
}
pub fn stripped_headers(&self) -> HeaderIter {
self.head.headers()
}
pub fn suffix(&self) -> &Path {
self.suffix
}
}