@@ -14,7 +14,7 @@ extern crate rand;
14
14
#[ macro_use]
15
15
extern crate diesel;
16
16
17
- use std:: io ;
17
+ use std:: { cmp , mem } ;
18
18
19
19
use actix:: prelude:: * ;
20
20
use actix_web:: server:: { self , HttpHandler , HttpHandlerTask , HttpServer , Writer } ;
@@ -27,8 +27,8 @@ mod db_pg;
27
27
mod models;
28
28
mod utils;
29
29
30
- use db_pg:: { PgConnection , TellFortune } ;
31
- use utils:: { Message , Writer as JsonWriter } ;
30
+ use db_pg:: { PgConnection , RandomWorld , RandomWorlds , TellFortune , UpdateWorld } ;
31
+ use utils:: { Message , StackWriter , Writer as JsonWriter } ;
32
32
33
33
const HTTPOK : & [ u8 ] = b"HTTP/1.1 200 OK\r \n " ;
34
34
const HDR_SERVER : & [ u8 ] = b"Server: Actix\r \n " ;
@@ -48,9 +48,45 @@ impl HttpHandler for App {
48
48
match path. len ( ) {
49
49
10 if path == "/plaintext" => return Ok ( Box :: new ( Plaintext ) ) ,
50
50
5 if path == "/json" => return Ok ( Box :: new ( Json ) ) ,
51
+ 3 if path == "/db" => {
52
+ return Ok ( Box :: new ( World {
53
+ fut : self . db . send ( RandomWorld ) ,
54
+ } ) )
55
+ }
51
56
8 if path == "/fortune" => {
52
- let fut = Box :: new ( self . db . send ( TellFortune ) ) ;
53
- return Ok ( Box :: new ( Fortune { fut } ) ) ;
57
+ return Ok ( Box :: new ( Fortune {
58
+ fut : self . db . send ( TellFortune ) ,
59
+ } ) ) ;
60
+ }
61
+ 8 if path == "/queries" => {
62
+ let q = req
63
+ . query ( )
64
+ . get ( "q" )
65
+ . map ( |q| {
66
+ cmp:: min (
67
+ 500 ,
68
+ cmp:: max ( 1 , q. parse :: < u16 > ( ) . ok ( ) . unwrap_or ( 1 ) ) ,
69
+ )
70
+ } )
71
+ . unwrap_or ( 1 ) ;
72
+ return Ok ( Box :: new ( Queries {
73
+ fut : self . db . send ( RandomWorlds ( q) ) ,
74
+ } ) ) ;
75
+ }
76
+ 8 if path == "/updates" => {
77
+ let q = req
78
+ . query ( )
79
+ . get ( "q" )
80
+ . map ( |q| {
81
+ cmp:: min (
82
+ 500 ,
83
+ cmp:: max ( 1 , q. parse :: < u16 > ( ) . ok ( ) . unwrap_or ( 1 ) ) ,
84
+ )
85
+ } )
86
+ . unwrap_or ( 1 ) ;
87
+ return Ok ( Box :: new ( Updates {
88
+ fut : self . db . send ( UpdateWorld ( q) ) ,
89
+ } ) ) ;
54
90
}
55
91
_ => ( ) ,
56
92
}
@@ -96,9 +132,7 @@ impl HttpHandlerTask for Json {
96
132
}
97
133
98
134
struct Fortune {
99
- fut : Box <
100
- Future < Item = io:: Result < Vec < models:: Fortune > > , Error = actix:: MailboxError > ,
101
- > ,
135
+ fut : actix:: dev:: Request < Syn , PgConnection , TellFortune > ,
102
136
}
103
137
104
138
#[ derive( Template ) ]
@@ -111,17 +145,118 @@ impl HttpHandlerTask for Fortune {
111
145
fn poll_io ( & mut self , io : & mut Writer ) -> Poll < bool , Error > {
112
146
match self . fut . poll ( ) {
113
147
Ok ( Async :: Ready ( Ok ( rows) ) ) => {
114
- let tmpl = FortuneTemplate { items : & rows } ;
115
- let body = tmpl. render ( ) . unwrap ( ) ;
148
+ let mut body: [ u8 ; 2048 ] = unsafe { mem:: uninitialized ( ) } ;
149
+ let len = {
150
+ let mut writer = StackWriter ( & mut body, 0 ) ;
151
+ let tmpl = FortuneTemplate { items : & rows } ;
152
+ tmpl. render_into ( & mut writer) . unwrap ( ) ;
153
+ writer. 1
154
+ } ;
116
155
117
156
let mut bytes = io. buffer ( ) ;
118
- bytes. reserve ( 196 + body . len ( ) ) ;
157
+ bytes. reserve ( 196 + len) ;
119
158
bytes. extend_from_slice ( HTTPOK ) ;
120
159
bytes. extend_from_slice ( HDR_SERVER ) ;
121
160
bytes. extend_from_slice ( HDR_CTHTML ) ;
122
- server:: write_content_length ( body. len ( ) , & mut bytes) ;
161
+ server:: write_content_length ( len, & mut bytes) ;
162
+ io. set_date ( bytes) ;
163
+ bytes. extend_from_slice ( & body[ ..len] ) ;
164
+ Ok ( Async :: Ready ( true ) )
165
+ }
166
+ Ok ( Async :: NotReady ) => Ok ( Async :: NotReady ) ,
167
+ Ok ( Async :: Ready ( Err ( e) ) ) => Err ( e. into ( ) ) ,
168
+ Err ( e) => Err ( e. into ( ) ) ,
169
+ }
170
+ }
171
+ }
172
+
173
+ struct World {
174
+ fut : actix:: dev:: Request < Syn , PgConnection , RandomWorld > ,
175
+ }
176
+
177
+ impl HttpHandlerTask for World {
178
+ fn poll_io ( & mut self , io : & mut Writer ) -> Poll < bool , Error > {
179
+ match self . fut . poll ( ) {
180
+ Ok ( Async :: Ready ( Ok ( row) ) ) => {
181
+ let mut body: [ u8 ; 48 ] = unsafe { mem:: uninitialized ( ) } ;
182
+ let len = {
183
+ let mut writer = StackWriter ( & mut body, 0 ) ;
184
+ serde_json:: to_writer ( & mut writer, & row) . unwrap ( ) ;
185
+ writer. 1
186
+ } ;
187
+
188
+ let mut bytes = io. buffer ( ) ;
189
+ bytes. reserve ( 196 ) ;
190
+ bytes. extend_from_slice ( HTTPOK ) ;
191
+ bytes. extend_from_slice ( HDR_SERVER ) ;
192
+ bytes. extend_from_slice ( HDR_CTJSON ) ;
193
+ server:: write_content_length ( len, & mut bytes) ;
194
+ io. set_date ( bytes) ;
195
+ bytes. extend_from_slice ( & body[ ..len] ) ;
196
+ Ok ( Async :: Ready ( true ) )
197
+ }
198
+ Ok ( Async :: NotReady ) => Ok ( Async :: NotReady ) ,
199
+ Ok ( Async :: Ready ( Err ( e) ) ) => Err ( e. into ( ) ) ,
200
+ Err ( e) => Err ( e. into ( ) ) ,
201
+ }
202
+ }
203
+ }
204
+
205
+ struct Queries {
206
+ fut : actix:: dev:: Request < Syn , PgConnection , RandomWorlds > ,
207
+ }
208
+
209
+ impl HttpHandlerTask for Queries {
210
+ fn poll_io ( & mut self , io : & mut Writer ) -> Poll < bool , Error > {
211
+ match self . fut . poll ( ) {
212
+ Ok ( Async :: Ready ( Ok ( worlds) ) ) => {
213
+ let mut body: [ u8 ; 24576 ] = unsafe { mem:: uninitialized ( ) } ;
214
+ let len = {
215
+ let mut writer = StackWriter ( & mut body, 0 ) ;
216
+ serde_json:: to_writer ( & mut writer, & worlds) . unwrap ( ) ;
217
+ writer. 1
218
+ } ;
219
+
220
+ let mut bytes = io. buffer ( ) ;
221
+ bytes. reserve ( 196 + len) ;
222
+ bytes. extend_from_slice ( HTTPOK ) ;
223
+ bytes. extend_from_slice ( HDR_SERVER ) ;
224
+ bytes. extend_from_slice ( HDR_CTJSON ) ;
225
+ server:: write_content_length ( len, & mut bytes) ;
226
+ io. set_date ( bytes) ;
227
+ bytes. extend_from_slice ( & body[ ..len] ) ;
228
+ Ok ( Async :: Ready ( true ) )
229
+ }
230
+ Ok ( Async :: NotReady ) => Ok ( Async :: NotReady ) ,
231
+ Ok ( Async :: Ready ( Err ( e) ) ) => Err ( e. into ( ) ) ,
232
+ Err ( e) => Err ( e. into ( ) ) ,
233
+ }
234
+ }
235
+ }
236
+
237
+ struct Updates {
238
+ fut : actix:: dev:: Request < Syn , PgConnection , UpdateWorld > ,
239
+ }
240
+
241
+ impl HttpHandlerTask for Updates {
242
+ fn poll_io ( & mut self , io : & mut Writer ) -> Poll < bool , Error > {
243
+ match self . fut . poll ( ) {
244
+ Ok ( Async :: Ready ( Ok ( worlds) ) ) => {
245
+ let mut body: [ u8 ; 24576 ] = unsafe { mem:: uninitialized ( ) } ;
246
+ let len = {
247
+ let mut writer = StackWriter ( & mut body, 0 ) ;
248
+ serde_json:: to_writer ( & mut writer, & worlds) . unwrap ( ) ;
249
+ writer. 1
250
+ } ;
251
+
252
+ let mut bytes = io. buffer ( ) ;
253
+ bytes. reserve ( 196 + len) ;
254
+ bytes. extend_from_slice ( HTTPOK ) ;
255
+ bytes. extend_from_slice ( HDR_SERVER ) ;
256
+ bytes. extend_from_slice ( HDR_CTJSON ) ;
257
+ server:: write_content_length ( len, & mut bytes) ;
123
258
io. set_date ( bytes) ;
124
- bytes. extend_from_slice ( body. as_ref ( ) ) ;
259
+ bytes. extend_from_slice ( & body[ ..len ] ) ;
125
260
Ok ( Async :: Ready ( true ) )
126
261
}
127
262
Ok ( Async :: NotReady ) => Ok ( Async :: NotReady ) ,
0 commit comments