forked from nickel-org/nickel.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnickel.rs
148 lines (136 loc) · 4.66 KB
/
nickel.rs
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use std::fmt::Display;
use std::net::ToSocketAddrs;
use router::{Router, HttpRouter, Matcher};
use middleware::{MiddlewareStack, Middleware, ErrorHandler};
use server::Server;
use hyper::method::Method;
use hyper::status::StatusCode;
//pre defined middleware
use default_error_handler::DefaultErrorHandler;
/// Nickel is the application object. It's the surface that
/// holds all public APIs.
pub struct Nickel{
middleware_stack: MiddlewareStack,
}
impl HttpRouter for Nickel {
fn add_route<M: Into<Matcher>, H: Middleware>(&mut self, method: Method, matcher: M, handler: H) {
let mut router = Router::new();
router.add_route(method, matcher, handler);
self.utilize(router);
}
}
impl Nickel {
/// Creates an instance of Nickel with default error handling.
pub fn new() -> Nickel {
let mut middleware_stack = MiddlewareStack::new();
// Hook up the default error handler by default. Users are
// free to cancel it out from their custom error handler if
// they don't like the default behaviour.
middleware_stack.add_error_handler(DefaultErrorHandler);
Nickel { middleware_stack: middleware_stack }
}
/// Registers a middleware handler which will be invoked among other middleware
/// handlers before each request. Middleware can be stacked and is invoked in the
/// same order it was registered.
///
/// A middleware handler is nearly identical to a regular route handler with the only
/// difference that it expects a result of either Action or NickelError.
/// That is to indicate whether other middleware handlers (if any) further
/// down the stack should continue or if the middleware invocation should
/// be stopped after the current handler.
///
/// # Examples
/// ```{rust}
/// # #[macro_use] extern crate nickel;
/// # fn main() {
/// use nickel::Nickel;
/// let mut server = Nickel::new();
/// server.utilize(middleware! { |req|
/// println!("logging request: {:?}", req.origin.uri);
/// });
/// # }
/// ```
pub fn utilize<T: Middleware>(&mut self, handler: T){
self.middleware_stack.add_middleware(handler);
}
/// Registers an error handler which will be invoked among other error handler
/// as soon as any regular handler returned an error
///
/// A error handler is nearly identical to a regular middleware handler with the only
/// difference that it takes an additional error parameter or type `NickelError.
///
/// # Examples
///
/// ```{rust}
/// # extern crate nickel;
/// # fn main() {
/// use std::io::Write;
/// use nickel::{Nickel, Request, Response, Continue, Halt};
/// use nickel::{NickelError, Action};
/// use nickel::status::StatusCode::NotFound;
///
/// fn error_handler(err: &mut NickelError, req: &mut Request) -> Action {
/// if let Some(ref mut res) = err.stream {
/// if res.status() == NotFound {
/// let _ = res.write_all(b"<h1>Call the police!</h1>");
/// return Halt(())
/// }
/// }
///
/// Continue(())
/// }
///
/// let mut server = Nickel::new();
///
/// let ehandler: fn(&mut NickelError, &mut Request) -> Action = error_handler;
///
/// server.handle_error(ehandler)
/// # }
/// ```
pub fn handle_error<T: ErrorHandler>(&mut self, handler: T){
self.middleware_stack.add_error_handler(handler);
}
/// Create a new middleware to serve as a router.
///
///
/// # Examples
/// ```{rust}
/// #[macro_use] extern crate nickel;
/// use nickel::{Nickel, HttpRouter};
///
/// fn main() {
/// let mut server = Nickel::new();
/// let mut router = Nickel::router();
///
/// router.get("/foo", middleware! {
/// "Hi from /foo"
/// });
///
/// server.utilize(router);
/// }
/// ```
pub fn router() -> Router {
Router::new()
}
/// Bind and listen for connections on the given host and port.
///
/// # Panics
///
/// Panics if `addr` is an invalid `SocketAddr`.
///
/// # Examples
/// ```{rust,no_run}
/// use nickel::Nickel;
///
/// let mut server = Nickel::new();
/// server.listen("127.0.0.1:6767");
/// ```
pub fn listen<T: ToSocketAddrs + Display>(mut self, addr: T) {
self.middleware_stack.add_middleware(middleware! {
(StatusCode::NotFound, "File Not Found")
});
println!("Listening on http://{}", addr);
println!("Ctrl-C to shutdown server");
Server::new(self.middleware_stack).serve(addr);
}
}