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 |
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 |