-
Notifications
You must be signed in to change notification settings - Fork 11
/
hello_world_server.rs
124 lines (112 loc) · 3.29 KB
/
hello_world_server.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
extern crate rotor;
extern crate rotor_http;
use std::time::Duration;
use rotor::{Scope, Time};
use rotor_http::server::{RecvMode, Server, Head, Response, Fsm};
use rotor::mio::tcp::TcpListener;
struct Context {
counter: usize,
}
trait Counter {
fn increment(&mut self);
fn get(&self) -> usize;
}
impl Counter for Context {
fn increment(&mut self) { self.counter += 1; }
fn get(&self) -> usize { self.counter }
}
#[derive(Debug, Clone)]
enum HelloWorld {
Hello,
GetNum,
HelloName(String),
PageNotFound,
}
fn send_string(res: &mut Response, data: &[u8]) {
res.status(200, "OK");
res.add_length(data.len() as u64).unwrap();
res.done_headers().unwrap();
res.write_body(data);
res.done();
}
impl Server for HelloWorld {
type Seed = ();
type Context = Context;
fn headers_received(_seed: (), head: Head, _res: &mut Response,
scope: &mut Scope<Context>)
-> Option<(Self, RecvMode, Time)>
{
use self::HelloWorld::*;
scope.increment();
Some((match head.path {
"/" => Hello,
"/num" => GetNum,
p if p.starts_with('/') => HelloName(p[1..].to_string()),
_ => PageNotFound
}, RecvMode::Buffered(1024),
scope.now() + Duration::new(10, 0)))
}
fn request_received(self, _data: &[u8], res: &mut Response,
scope: &mut Scope<Context>)
-> Option<Self>
{
use self::HelloWorld::*;
match self {
Hello => {
send_string(res, b"Hello World!");
}
GetNum => {
send_string(res,
format!("This host has been visited {} times",
scope.get())
.as_bytes());
}
HelloName(name) => {
send_string(res, format!("Hello {}!", name).as_bytes());
}
PageNotFound => {
let data = b"404 - Page not found";
res.status(404, "Not Found");
res.add_length(data.len() as u64).unwrap();
res.done_headers().unwrap();
res.write_body(data);
res.done();
}
}
None
}
fn request_chunk(self, _chunk: &[u8], _response: &mut Response,
_scope: &mut Scope<Context>)
-> Option<Self>
{
unreachable!();
}
/// End of request body, only for Progressive requests
fn request_end(self, _response: &mut Response, _scope: &mut Scope<Context>)
-> Option<Self>
{
unreachable!();
}
fn timeout(self, _response: &mut Response, _scope: &mut Scope<Context>)
-> Option<(Self, Time)>
{
unimplemented!();
}
fn wakeup(self, _response: &mut Response, _scope: &mut Scope<Context>)
-> Option<Self>
{
unimplemented!();
}
}
fn main() {
println!("Starting http server on http://127.0.0.1:3000/");
let event_loop = rotor::Loop::new(&rotor::Config::new()).unwrap();
let mut loop_inst = event_loop.instantiate(Context {
counter: 0,
});
let lst = TcpListener::bind(&"127.0.0.1:3000".parse().unwrap()).unwrap();
loop_inst.add_machine_with(|scope| {
Fsm::<HelloWorld, _>::new(lst, (), scope)
}).unwrap();
loop_inst.run().unwrap();
}