src/server/daemon/sessionhandler.c

changeset 554
e0a6b761ddbc
parent 546
5494c28db896
child 555
66b0accda0a8
equal deleted inserted replaced
553:a166a15f7b74 554:e0a6b761ddbc
40 #include "httplistener.h" 40 #include "httplistener.h"
41 41
42 struct EventHttpIO { 42 struct EventHttpIO {
43 HTTPRequest *request; 43 HTTPRequest *request;
44 HttpParser *parser; 44 HttpParser *parser;
45 EVWatchList watch;
46 Event *io_event;
45 int error; 47 int error;
46 }; 48 };
47 49
48 50
49 int connection_read(Connection *conn, void *buf, int len) { 51 int connection_read(Connection *conn, void *buf, int len) {
219 handler->sh.keep_alive = evt_keep_alive; 221 handler->sh.keep_alive = evt_keep_alive;
220 handler->sh.create_iostream = create_connection_iostream; 222 handler->sh.create_iostream = create_connection_iostream;
221 return (SessionHandler*)handler; 223 return (SessionHandler*)handler;
222 } 224 }
223 225
226 void evt_request_timeout(EventHandler *h, EVWatchList *item) {
227 log_ereport(LOG_VERBOSE, "sessionhandler: request timeout");
228 item->intdata = 0;
229
230 EventHttpIO *io = item->data1;
231 io->error = 4;
232
233 if(ev_remove_poll(h, io->request->connection->fd)) {
234 log_ereport(LOG_FAILURE, "sessionhandler: request timeout: cannot remove poll");
235 }
236 evt_request_error(h, io->io_event);
237 }
238
239 int evt_add_request_timeout(EventHandler *h, Event *event) {
240 EventHttpIO *io = event->cookie;
241 io->watch.intdata = 1;
242 ev_watchlist_add(h, &io->watch);
243 return 0;
244 }
245
224 void evt_enq_conn(SessionHandler *handler, Connection *conn) { 246 void evt_enq_conn(SessionHandler *handler, Connection *conn) {
225 Event *event = malloc(sizeof(Event)); 247 Event *event = malloc(sizeof(Event));
226 if(!event) { 248 if(!event) {
227 connection_destroy(conn); 249 connection_destroy(conn);
228 return; 250 return;
243 265
244 ZERO(event, sizeof(Event)); 266 ZERO(event, sizeof(Event));
245 event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input; 267 event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input;
246 event->finish = evt_request_finish; 268 event->finish = evt_request_finish;
247 event->cookie = io; 269 event->cookie = io;
270 io->io_event = event;
248 271
249 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler); 272 EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler);
250 273
251 if(ev_pollin(ev, conn->fd, event) != 0) { 274 if(ev_pollin(ev, conn->fd, event) != 0) {
252 // TODO: ev_pollin should log, intercept some errors here 275 // TODO: ev_pollin should log, intercept some errors here
253 log_ereport(LOG_FAILURE, "Cannot enqueue connection"); 276 log_ereport(LOG_FAILURE, "Cannot enqueue connection");
254 evt_request_error(ev, event); 277 evt_request_error(ev, event);
278 } else {
279 // add request timeout
280 io->watch.created = time(NULL);
281 io->watch.expire = io->watch.created + 240; // TODO: config
282 io->watch.destroy = evt_request_timeout;
283 io->watch.data1 = io;
284
285 Event *add_timeout = malloc(sizeof(Event));
286 if(add_timeout) {
287 add_timeout->cookie = io;
288 add_timeout->fn = evt_add_request_timeout;
289 add_timeout->finish = ev_free_event;
290 add_timeout->error = 0;
291 if(event_send(ev, add_timeout)) {
292 log_ereport(LOG_FAILURE, "Cannot add request timeout: event_send failed");
293 }
294 } else {
295 // not an error that breaks everything, a log message is enough
296 log_ereport(LOG_FAILURE, "Cannot add request timeout: OOM");
297 }
255 } 298 }
256 } 299 }
257 300
258 EventHttpIO* evt_req_init(SessionHandler *handler, Connection *conn) { 301 EventHttpIO* evt_req_init(SessionHandler *handler, Connection *conn) {
259 // set socket non blocking 302 // set socket non blocking
314 return NULL; 357 return NULL;
315 } 358 }
316 io->request = request; 359 io->request = request;
317 io->parser = parser; 360 io->parser = parser;
318 io->error = 0; 361 io->error = 0;
362 ZERO(&io->watch, sizeof(EVWatchList));
319 363
320 return io; 364 return io;
321 } 365 }
322 366
323 int evt_request_ssl_accept(EventHandler *handler, Event *event) { 367 int evt_request_ssl_accept(EventHandler *handler, Event *event) {
444 488
445 int evt_request_finish(EventHandler *h, Event *event) { 489 int evt_request_finish(EventHandler *h, Event *event) {
446 EventHttpIO *io = event->cookie; 490 EventHttpIO *io = event->cookie;
447 HttpParser *parser = io->parser; 491 HttpParser *parser = io->parser;
448 HTTPRequest *request = io->request; 492 HTTPRequest *request = io->request;
493
494 // remove timeout
495 if(io->watch.intdata) {
496 ev_watchlist_remove(h, &io->watch);
497 }
449 498
450 int r = handle_request(request, NULL, h); 499 int r = handle_request(request, NULL, h);
451 if(r != 0) { 500 if(r != 0) {
452 connection_destroy(request->connection); 501 connection_destroy(request->connection);
453 free(request->netbuf->inbuf); 502 free(request->netbuf->inbuf);
474 HttpParser *parser = io->parser; 523 HttpParser *parser = io->parser;
475 HTTPRequest *request = io->request; 524 HTTPRequest *request = io->request;
476 525
477 if(event->error) { 526 if(event->error) {
478 log_ereport(LOG_VERBOSE, "sessionhandler http io error: %d fd: %d", io->error, request->connection->fd); 527 log_ereport(LOG_VERBOSE, "sessionhandler http io error: %d fd: %d", io->error, request->connection->fd);
528 }
529
530 // remove timeout
531 if(io->watch.intdata) {
532 ev_watchlist_remove(h, &io->watch);
479 } 533 }
480 534
481 free(request->netbuf->inbuf); 535 free(request->netbuf->inbuf);
482 free(request->netbuf); 536 free(request->netbuf);
483 537

mercurial