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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
use std::time::Duration;
use rotor::{Scope, Time};
use recvmode::RecvMode;
use super::error::HttpError;
use super::request::Head;
use super::Response;
/// A handler of server-side HTTP
///
/// Used for all versions of HTTP
pub trait Server: Sized {
type Context;
/// Each request gets a clone of a Seed in `headers_received()` handler
type Seed: Clone;
/// Encountered when headers received.
///
/// Returns self, mode and timeout for reading whole request.
///
/// This handler decides whether a request is fully buffered or whether
/// we need to read request body by chunk. It's recommended to return
/// Buffered up to certain size, or at least for zero-length requests.
///
/// You may start building a response right here, or wait for
/// the next event.
///
/// In case there is Expect header, the successful (non-None) return of
/// this handler means we should return a `100 Expect` result. But if you
/// have started building response right here, we skip expect header, as
/// normal response code is good enough for browser. (Are there ugly
/// proxies that propagate 100 Expect but does buffer response headers?)
///
/// Note that `head` is passed here once, and forgotten by the
/// protocol. If you need it later it's your responsibility to store it
/// somewhere.
fn headers_received(seed: Self::Seed, head: Head, response: &mut Response,
scope: &mut Scope<Self::Context>)
-> Option<(Self, RecvMode, Time)>;
/// Called when full request is received in buffered mode.
///
/// Note that even if you return None from handler, the data already
/// written in Response is used and rotor-http does as much as it can
/// to produce a valid response.
fn request_received(self, data: &[u8], response: &mut Response,
scope: &mut Scope<Self::Context>)
-> Option<Self>;
/// Called when request become invalid between `request_start()`
/// and `request_received/request_end`
///
/// You may put error page here if response is not `is_started()`. Or you
/// can finish response in case you can send something meaningfull anyway.
/// Otherwise, response will be filled with `BadRequest` from
/// `emit_error_page` or connection closed immediately (if `is_started()`
/// is true). You can't continue request processing after this handler is
/// called.
///
/// Currently it is called for two reasons:
///
/// 1. Invalid chunked encoding
/// 2. End of stream before number of bytes mentioned in Content-Length
///
/// It's never called on a timeout.
// TODO(tailhook) should there be some reason?
fn bad_request(self, _response: &mut Response,
_scope: &mut Scope<Self::Context>)
{}
/// Received chunk of data
///
/// Whey you return `Progressive(nbytes)` from headers received, you
/// may expect than chunk will be at least of `nbytes` of length. But
/// you must not rely on that for few reasons:
///
/// 1. Last chunk of request body may be smaller
/// 2. Chunk is read up to some buffer size, which is heuristically
/// determined, and is usually larger than `nbytes`
/// 3. Currently for chunked encoding we don't merge chunks, so last
/// part of each chunk may be shorter as `nbytes`
fn request_chunk(self, chunk: &[u8], response: &mut Response,
scope: &mut Scope<Self::Context>)
-> Option<Self>;
/// End of request body, only for Progressive requests
fn request_end(self, response: &mut Response,
scope: &mut Scope<Self::Context>)
-> Option<Self>;
/// Request timeout occurred
///
/// This is only called if headers are already received but state machine
/// is not yet finished. It drops down in two cases:
///
/// 1. Receiving request
/// 2. Sending response
///
/// If you received timeout you can return the new one, send error, or
/// finish response whatever you like. If response is not started yet at
/// the time method returns, client gets 408 error code.
///
/// Unless you've returned the new timeout connection will be closed after
/// the event.
fn timeout(self, response: &mut Response, scope: &mut Scope<Self::Context>)
-> Option<(Self, Time)>;
fn wakeup(self, response: &mut Response, scope: &mut Scope<Self::Context>)
-> Option<Self>;
/// A bad request occured
///
/// You should send a complete response in this handler.
///
/// This is a static method, since it often called when there is no
/// instance of request at all. You may override a page for specific
/// request in `bad_request()` handler, if request headers are already
/// parsed. If `bad_request()` emits anything this method is not called.
///
/// You may also use (parts of) `seed` value or a context to determine
/// the correct error page.
///
/// You can also fallback to a default handler for pages you don't want
/// to render.
fn emit_error_page(code: &HttpError, response: &mut Response,
_seed: &Self::Seed, _scope: &mut Scope<Self::Context>)
{
let (status, reason) = code.http_status();
response.status(status, reason);
let data = format!("<h1>{} {}</h1>\n\
<p><small>Served for you by rotor-http</small></p>\n",
status, reason);
let bytes = data.as_bytes();
response.add_length(bytes.len() as u64).unwrap();
response.add_header("Content-Type", b"text/html").unwrap();
response.done_headers().unwrap();
response.write_body(bytes);
response.done();
}
/// A timeout for idle keep-alive connection
///
/// Default is 120 seconds
fn idle_timeout(_seed: &Self::Seed, _scope: &mut Scope<Self::Context>)
-> Duration
{
return Duration::new(120, 0);
}
/// A timeout for receiving at least one byte from headers
///
/// Default is 45 seconds
fn header_byte_timeout(_seed: &Self::Seed,
_scope: &mut Scope<Self::Context>)
-> Duration
{
return Duration::new(45, 0);
}
/// A timeout for sending full response body to the (slow) client
///
/// Default is 3600 seconds (one hour)
fn send_response_timeout(_seed: &Self::Seed,
_scope: &mut Scope<Self::Context>)
-> Duration
{
return Duration::new(3600, 0);
}
}