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 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32
33 #include "../public/nsapi.h"
34
35 #include "sessionhandler.h"
36 #include "httprequest.h"
37 #include "httpparser.h"
38 #include "log.h"
39 #include "error.h"
40 #include "httplistener.h"
41
42 typedef struct _event_http_io {
43 HTTPRequest *request;
44 HttpParser *parser;
45 int error;
46 } EventHttpIO;
47
48
49 int connection_read(Connection *conn,
void *buf,
int len) {
50 return (
int)read(conn->fd, buf, len);
51 }
52
53 int connection_write(Connection *conn,
const void *buf,
int len) {
54 return (
int)write(conn->fd, buf, len);
55 }
56
57 void connection_close(Connection *conn) {
58 while(close(conn->fd)) {
59 if(errno !=
EINTR) {
60 log_ereport(
LOG_VERBOSE,
"connection close failed: %s", strerror(errno));
61 break;
62 }
63 log_ereport(
LOG_VERBOSE,
"connection close: EINTR");
64 }
65 }
66
67 int connection_ssl_read(Connection *conn,
void *buf,
int len) {
68 int ret = SSL_read(conn->ssl, buf, len);
69 if(ret <=
0) {
70 conn->ssl_error = SSL_get_error(conn->ssl, ret);
71 }
72 return ret;
73 }
74
75 int connection_ssl_write(Connection *conn,
const void *buf,
int len) {
76 int ret = SSL_write(conn->ssl, buf, len);
77 if(ret <=
0) {
78 conn->ssl_error = SSL_get_error(conn->ssl, ret);
79 }
80 return ret;
81 }
82
83 void connection_ssl_close(Connection *conn) {
84 if(!conn->ssl_error) {
85 int ret = SSL_shutdown(conn->ssl);
86 if(ret !=
1) {
87 conn->ssl_error = SSL_get_error(conn->ssl, ret);
88 log_ereport(
LOG_VERBOSE,
"SSL_shutdown failed: %d", conn->ssl_error);
89 }
90 }
91 while(close(conn->fd)) {
92 if(errno !=
EINTR) {
93 log_ereport(
LOG_VERBOSE,
"connection close failed: %s", strerror(errno));
94 break;
95 }
96 log_ereport(
LOG_VERBOSE,
"connection close: EINTR");
97 }
98 }
99
100 void connection_destroy(Connection *conn) {
101 conn->close(conn);
102 if(conn->ssl) {
103 SSL_free(conn->ssl);
104 }
105 free(conn);
106 }
107
108 IOStream* create_connection_iostream(
109 SessionHandler *sh,
110 Connection *conn,
111 pool_handle_t *pool,
112 WSBool *ssl)
113 {
114 IOStream *io =
NULL;
115 if(conn->ssl) {
116 io = sslstream_new(pool, conn->ssl);
117 *ssl =
1;
118 }
else {
119 io = sysstream_new(pool, conn->fd);
120 *ssl =
0;
121 }
122 return io;
123 }
124
125
126 SessionHandler* create_basic_session_handler() {
127 BasicSessionHandler *handler = malloc(
sizeof(BasicSessionHandler));
128 handler->threadpool = threadpool_new(
4,
8);
129 handler->sh.enqueue_connection = basic_enq_conn;
130 handler->sh.keep_alive = basic_keep_alive;
131 handler->sh.create_iostream = create_connection_iostream;
132
133 return (SessionHandler*)handler;
134 }
135
136 void basic_enq_conn(SessionHandler *handler, Connection *conn) {
137 BasicSessionHandler *sh = (BasicSessionHandler*)handler;
138 conn->session_handler = handler;
139 threadpool_run(sh->threadpool, basic_run_session, conn);
140 }
141
142 void* basic_run_session(
void *data) {
143 Connection *conn = (Connection*)data;
144
145 HTTPRequest request;
146 http_request_init(&request);
147 request.connection = conn;
148
149
150 netbuf *buf = malloc(
sizeof(netbuf));
151 buf->rdtimeout =
120;
152 buf->pos =
0;
153 buf->cursize =
0;
154 buf->maxsize =
2048;
155 buf->sd = &conn->fd;
156 buf->inbuf = malloc(
2048);
157 buf->errmsg =
NULL;
158
159 request.netbuf = buf;
160
161 HttpParser *parser = http_parser_new(&request);
162 int state;
163 int r;
164 r = conn->read(conn, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
165 if(r <=
0) {
166
167 fprintf(stderr,
"%s\n",
"Error: Cannot read from socket");
168 return NULL;
169 }
170 buf->cursize += r;
171 while((state = http_parser_process(parser)) !=
0) {
172 if(state ==
2) {
173
174 fprintf(stderr,
"%s\n",
"Error: Cannot parse http request");
175 return NULL;
176 }
177 r = conn->read(conn, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
178 if(r == -
1) {
179
180 fprintf(stderr,
"%s\n",
"Error: Cannot read from socket");
181 return NULL;
182 }
183 buf->cursize += r;
184 }
185 if(!http_parser_validate(parser)) {
186 log_ereport(
LOG_FAILURE,
"http_parser_validate failed");
187
188 return NULL;
189 }
190
191
192 r = handle_request(&request,
NULL,
NULL);
193
194
195
196 return NULL;
197 }
198
199 void basic_keep_alive(SessionHandler *handler, Connection *conn) {
200 connection_destroy(conn);
201 }
202
203
204
205
206 SessionHandler* create_event_session_handler() {
207 EventSessionHandler *handler = malloc(
sizeof(EventSessionHandler));
208 handler->eventhandler = get_default_event_handler();
209 handler->sh.enqueue_connection = evt_enq_conn;
210 handler->sh.keep_alive = evt_keep_alive;
211 handler->sh.create_iostream = create_connection_iostream;
212 return (SessionHandler*)handler;
213 }
214
215 void evt_enq_conn(SessionHandler *handler, Connection *conn) {
216 HTTPRequest *request = malloc(
sizeof(HTTPRequest));
217 http_request_init(request);
218 request->connection = conn;
219 conn->session_handler = handler;
220
221
222 int flags;
223 if ((flags = fcntl(conn->fd,
F_GETFL,
0)) == -
1) {
224 flags =
0;
225 }
226 if (fcntl(conn->fd,
F_SETFL, flags |
O_NONBLOCK) !=
0) {
227 perror(
"Error: start_event_session: fcntl");
228
229 }
230
231
232
233
234 netbuf *buf = malloc(
sizeof(netbuf));
235 buf->rdtimeout =
120;
236 buf->pos =
0;
237 buf->cursize =
0;
238 buf->maxsize =
2048;
239 buf->sd = &conn->fd;
240 buf->inbuf = malloc(
2048);
241 buf->errmsg =
NULL;
242
243 request->netbuf = buf;
244
245 HttpParser *parser = http_parser_new(request);
246
247 EventHttpIO *io = malloc(
sizeof(EventHttpIO));
248 if(io ==
NULL) {
249
250 }
251 io->request = request;
252 io->parser = parser;
253 io->error =
0;
254
255
256
257
258
259
260
261 Event *event = malloc(
sizeof(Event));
262 ZERO(event,
sizeof(Event));
263 event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input;
264 event->finish = evt_request_finish;
265 event->cookie = io;
266
267 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler);
268
269 if(ev_pollin(ev, conn->fd, event) !=
0) {
270
271 log_ereport(
LOG_FAILURE,
"Cannot enqueue connection");
272 connection_destroy(conn);
273
274 }
275 }
276
277 int evt_request_ssl_accept(EventHandler *handler, Event *event) {
278 EventHttpIO *io = event->cookie;
279 Connection *conn = io->request->connection;
280
281 int ret = SSL_accept(conn->ssl);
282 if(ret <=
0) {
283 int error = SSL_get_error(conn->ssl, ret);
284 char *errstr;
285 switch(error) {
286 default: errstr =
"unknown";
break;
287 case SSL_ERROR_WANT_READ: {
288 event->events =
EVENT_POLLIN;
289 return 1;
290 }
291 case SSL_ERROR_WANT_WRITE: {
292 event->events =
EVENT_POLLOUT;
293 return 1;
294 }
295 case SSL_ERROR_ZERO_RETURN: errstr =
"SSL_ERROR_ZERO_RETURN";
break;
296 case SSL_ERROR_WANT_CONNECT: errstr =
"SSL_ERROR_WANT_CONNECT";
break;
297 case SSL_ERROR_WANT_ACCEPT: errstr =
"SSL_ERROR_WANT_ACCEPT";
break;
298 case SSL_ERROR_WANT_X509_LOOKUP: errstr =
"SSL_ERROR_WANT_X509_LOOKUP";
break;
299 case SSL_ERROR_SYSCALL: errstr =
"SSL_ERROR_SYSCALL";
break;
300 case SSL_ERROR_SSL: errstr =
"SSL_ERROR_SSL";
break;
301 }
302 log_ereport(
LOG_VERBOSE,
"SSL accept error[%d]: %s", error, errstr);
303 event->finish = evt_request_error;
304 io->error =
1;
305 return 0;
306 }
307 conn->ssl_accepted =
WS_TRUE;
308
309
310 event->fn = evt_request_input;
311 return evt_request_input(handler, event);
312 }
313
314 int evt_request_input(EventHandler *handler, Event *event) {
315 EventHttpIO *io = event->cookie;
316 HttpParser *parser = io->parser;
317 HTTPRequest *request = io->request;
318 Connection *conn = io->request->connection;
319 netbuf *buf = request->netbuf;
320
321 int state;
322 int r;
323 r = conn->read(
324 conn,
325 buf->inbuf + buf->pos,
326 buf->maxsize - buf->pos);
327 if(r <=
0) {
328 if(conn->ssl) {
329
330 switch(conn->ssl_error) {
331 case SSL_ERROR_WANT_READ: {
332 event->events =
EVENT_POLLIN;
333 return 1;
334 }
335 case SSL_ERROR_WANT_WRITE: {
336 event->events =
EVENT_POLLOUT;
337 return 1;
338 }
339 }
340 }
341
342 event->finish = evt_request_error;
343 io->error =
1;
344 return 0;
345 }
346
347
348
349 buf->cursize += r;
350 state = http_parser_process(parser);
351 if(state ==
2) {
352
353 fatal_error(request,
400);
354 event->finish = evt_request_error;
355 io->error =
2;
356 return 0;
357 }
else if(state ==
1) {
358
359
360
361
362 event->events =
EVENT_POLLIN;
363 return 1;
364 }
365
366
367
368
369 int flags;
370 if (-
1 == (flags = fcntl(request->connection->fd,
F_GETFL,
0))) {
371 flags =
0;
372 }
373 if (fcntl(request->connection->fd,
F_SETFL, flags & ~
O_NONBLOCK) !=
0) {
374
375 event->finish = evt_request_error;
376 io->error =
3;
377 return 0;
378 }
379
380 if(!http_parser_validate(parser)) {
381 log_ereport(
LOG_FAILURE,
"http_parser_validate failed");
382
383 event->finish = evt_request_error;
384 return 0;
385 }
386
387
388
389
390
391
392
393 return 0;
394 }
395
396 int evt_request_finish(EventHandler *h, Event *event) {
397 EventHttpIO *io = event->cookie;
398 HttpParser *parser = io->parser;
399 HTTPRequest *request = io->request;
400
401 int r = handle_request(request,
NULL, h);
402 if(r !=
0) {
403
404 connection_destroy(request->connection);
405 }
406
407
408
409
410
411
412
413 http_request_cleanup(request);
414 http_parser_free(parser);
415
416 free(io);
417 free(event);
418
419 return 0;
420 }
421
422 int evt_request_error(EventHandler *h, Event *event) {
423 EventHttpIO *io = event->cookie;
424 HttpParser *parser = io->parser;
425 HTTPRequest *request = io->request;
426
427 if(event->error) {
428 log_ereport(
LOG_VERBOSE,
"sessionhandler http io error: %d fd: %d", io->error, request->connection->fd);
429 }
430
431 free(request->netbuf->inbuf);
432 free(request->netbuf);
433
434 cfg_unref(request->connection->listener->cfg);
435 connection_destroy(request->connection);
436
437 http_request_cleanup(request);
438 http_parser_free(parser);
439
440 free(io);
441 free(event);
442
443 return 0;
444 }
445
446 void evt_keep_alive(SessionHandler *handler, Connection *conn) {
447
448
449
450
451
452
453
454
455
456
457
458
459
460 evt_enq_conn(handler, conn);
461 }
462