diff -r 2b4574e617c0 -r 4417619a9bbd src/server/daemon/sessionhandler.c --- 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); +}