Sat, 18 Aug 2012 11:39:34 +0200
using non blocking IO for request input
--- a/src/server/daemon/event.c Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/event.c Sat Aug 18 11:39:34 2012 +0200 @@ -94,3 +94,11 @@ return create_event_handler(&cfg); } + +event_handler_t* get_default_event_handler() { + return default_event_handler; +} + +event_handler_t* get_event_handler(char *name) { + return ucx_map_cstr_get(event_handler_map, name); +}
--- a/src/server/daemon/event.h Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/event.h Sat Aug 18 11:39:34 2012 +0200 @@ -65,6 +65,10 @@ int check_event_handler_cfg(); +event_handler_t* get_default_event_handler(); + +event_handler_t* get_event_handler(char *name); + /* implementation in event_$platform */ event_handler_t* evhandler_create(int numthreads);
--- a/src/server/daemon/event_solaris.c Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/event_solaris.c Sat Aug 18 11:39:34 2012 +0200 @@ -69,7 +69,10 @@ conf->handler = ev; conf->port = ev->ports[i]; - systhread_start(0, 0, (thrstartfunc)ev_handle_events, ev); + ev_thr_conf_t *thrconf = malloc(sizeof(ev_thr_conf_t)); + thrconf->handler = ev; + thrconf->port = ev->ports[i]; + systhread_start(0, 0, (thrstartfunc)ev_handle_events, thrconf); /* TODO: error handling */ } @@ -93,6 +96,7 @@ int ret = port_getn(port, events, 16, &nev, &timeout); if(ret == -1) { /* TODO: check for error */ + perror("port_getn"); continue; } @@ -109,7 +113,7 @@ int ev_get_port(event_handler_t *h) { int nps = h->nports; if(nps == 1) { - return 0; + return h->ports[0]; } int cp = h->lp % nps;
--- a/src/server/daemon/httplistener.c Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/httplistener.c Sat Aug 18 11:39:34 2012 +0200 @@ -80,7 +80,8 @@ HttpListener *listener = malloc(sizeof(HttpListener)); listener->name = conf->name; - listener->session_handler = create_basic_session_handler(); + //listener->session_handler = create_basic_session_handler(); + listener->session_handler = create_event_session_handler(); listener->nacceptors = conf->nacceptors; listener->port = conf->port; ucx_map_sstr_put(listener_map, listener->name, listener);
--- a/src/server/daemon/httprequest.c Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/httprequest.c Sat Aug 18 11:39:34 2012 +0200 @@ -28,6 +28,7 @@ #include <stdio.h> #include <stdlib.h> + #include <arpa/inet.h> #include "../public/nsapi.h" @@ -64,7 +65,13 @@ // create nsapi data structures NSAPISession *sn = malloc(sizeof(NSAPISession)); + if(sn == NULL) { + /* TODO: error */ + } NSAPIRequest *rq = malloc(sizeof(NSAPIRequest)); + if(rq == NULL) { + /* TODO: error */ + } request->rq = rq; rq->phase = NSAPIAuthTrans; @@ -336,6 +343,11 @@ r = nsapi_finish_request(sn, rq); } } + + if(r == REQ_ABORTED) { + nsapi_error_request(sn, rq); + } + } while (r == REQ_RESTART); r = nsapi_finish_request(sn, rq); @@ -350,6 +362,12 @@ return 0; } +int nsapi_error_request(NSAPISession *sn, NSAPIRequest *rq) { + // TODO + + return REQ_PROCEED; +} + int nsapi_authtrans(NSAPISession *sn, NSAPIRequest *rq) { HTTPObjectConfig *objconf = rq->vs->objects; httpd_object *obj = objconf->objects[0];
--- a/src/server/daemon/httprequest.h Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/httprequest.h Sat Aug 18 11:39:34 2012 +0200 @@ -79,6 +79,7 @@ int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq); int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq); +int nsapi_error_request(NSAPISession *sn, NSAPIRequest *rq); int nsapi_authtrans(NSAPISession *sn, NSAPIRequest *rq); int nsapi_nametrans(NSAPISession *sn, NSAPIRequest *rq);
--- a/src/server/daemon/sessionhandler.c Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/sessionhandler.c Sat Aug 18 11:39:34 2012 +0200 @@ -35,6 +35,11 @@ #include "httprequest.h" #include "httpparser.h" +typedef struct _event_http_io { + HTTPRequest *request; + HttpParser *parser; +} EventHttpIO; + SessionHandler* create_basic_session_handler() { BasicSessionHandler *handler = malloc(sizeof(BasicSessionHandler)); handler->threadpool = threadpool_new(8); @@ -100,4 +105,111 @@ return NULL; } +/* ----- event session handler ----- */ +SessionHandler* create_event_session_handler() { + EventSessionHandler *handler = malloc(sizeof(EventSessionHandler)); + handler->eventhandler = get_default_event_handler(); + handler->sh.enqueue_connection = evt_enq_conn; + return (SessionHandler*)handler; +} + +void evt_enq_conn(SessionHandler *handler, Connection *conn) { + HTTPRequest *request = http_request_new(); + request->connection = conn; + + // set socket non blocking + int flags; + if (-1 == (flags = fcntl(conn->fd, F_GETFL, 0))) { + flags = 0; + } + if (fcntl(conn->fd, F_SETFL, flags | O_NONBLOCK) != 0) { + perror("Error: start_event_session: fcntl"); + // TODO: error + } + + // TODO: remove code redundancy (basic_run_session) + + // read request + netbuf *buf = malloc(sizeof(netbuf)); + buf->rdtimeout = 120; + buf->pos = 0; + buf->cursize = 0; + buf->maxsize = 2048; + buf->sd = &conn->fd; + buf->inbuf = malloc(2048); + buf->errmsg = NULL; + + request->netbuf = buf; + + HttpParser *parser = http_parser_new(request); + + EventHttpIO *io = malloc(sizeof(EventHttpIO)); + if(io == NULL) { + // TODO: error handling + } + io->request = request; + io->parser = parser; + + /* + * to start the request handling, we begin with a poll on the socket, + * + * evt_enq_conn() --> event handler --> handle_request() + */ + + event_handler_t *ev = ((EventSessionHandler*)handler)->eventhandler; + + event_t *event = malloc(sizeof(event_t)); + event->fn = evt_request_input; + event->cookie = io; + + if(ev_pollin(ev, conn->fd, event) != 0) { + perror("poll"); + } +} + +void evt_request_input(event_handler_t *handler, event_t *event) { + EventHttpIO *io = event->cookie; + HttpParser *parser = io->parser; + HTTPRequest *request = io->request; + netbuf *buf = request->netbuf; + + int state; + int r; + r = read( + request->connection->fd, + buf->inbuf + buf->pos, + buf->maxsize - buf->pos); + if(r == -1) { + // TODO: error handling + fprintf(stderr, "%s\n", "Error: Cannot read from socket"); + return; + } + + buf->cursize += r; + state = http_parser_process(parser); + if(state == 2) { + // TODO: error handling + fprintf(stderr, "%s\n", "Error: Cannot parse http request"); + return; + } else if(state == 1) { + // we need more data -> begin poll, which repeats this function + ev_pollin(handler, request->connection->fd, event); + // TODO: check ev_pollin return value for errors + return; + } + + // we are done with reading + + // set socket blocking + int flags; + if (-1 == (flags = fcntl(request->connection->fd, F_GETFL, 0))) { + flags = 0; + } + if (fcntl(request->connection->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) { + perror("Error: evt_request_input: fcntl"); + // TODO: critical error + } + + r = handle_request(request); +}
--- a/src/server/daemon/sessionhandler.h Thu Aug 09 11:08:49 2012 +0200 +++ b/src/server/daemon/sessionhandler.h Sat Aug 18 11:39:34 2012 +0200 @@ -31,6 +31,7 @@ #include "../util/thrpool.h" #include "../public/nsapi.h" +#include "event.h" #ifdef __cplusplus extern "C" { @@ -54,8 +55,8 @@ /* * BasicSessionHandler * - * The BasicSessionHandler enqueues the connections to a threadpool. IO and - * request processing is handled by one thread. + * The BasicSessionHandler enqueues the connections to a threadpool. IO is + * handled by the threadpool. */ typedef struct _basic_session_handler { SessionHandler sh; @@ -63,6 +64,22 @@ } BasicSessionHandler; +/* + * EventSessionHandler + * + * The EventSessionHandler uses a event handler to handle request inputs. + */ +typedef struct _event_session_handler { + SessionHandler sh; + event_handler_t *eventhandler; +} EventSessionHandler; + +/* + * EventHttpIO + * + * defined in sesionhandler.c + */ + SessionHandler* create_basic_session_handler(); @@ -71,6 +88,12 @@ void* basic_run_session(void *data); +SessionHandler* create_event_session_handler(); + +void evt_enq_conn(SessionHandler *handler, Connection *conn); + +void evt_request_input(event_handler_t *h, event_t *event); + #ifdef __cplusplus }