src/server/daemon/sessionhandler.c

changeset 35
4417619a9bbd
parent 14
b8bf95b39952
child 36
450d2d5f4735
--- 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);
+}

mercurial