added keep-alive support

Tue, 25 Jun 2013 22:18:59 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 25 Jun 2013 22:18:59 +0200
changeset 78
3578977d29a3
parent 77
f1cff81e425a
child 79
f48cea237ec3

added keep-alive support

src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.h file | annotate | diff | comparison | revisions
src/server/daemon/protocol.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/httplistener.c	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/httplistener.c	Tue Jun 25 22:18:59 2013 +0200
@@ -150,8 +150,8 @@
     if(listener->threadpool == NULL) {
         listener->threadpool = get_default_threadpool();
     }
-    listener->session_handler = create_basic_session_handler();
-    //listener->session_handler = create_event_session_handler();
+    //listener->session_handler = create_basic_session_handler();
+    listener->session_handler = create_event_session_handler();
     listener->nacceptors = conf->nacceptors;
     listener->port = conf->port;
     listener->ref = 1;
--- a/src/server/daemon/httprequest.c	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/httprequest.c	Tue Jun 25 22:18:59 2013 +0200
@@ -70,7 +70,6 @@
     if(rq == NULL) {
         /* TODO: error */
     }
-    request->rq = rq;
     rq->phase = NSAPIAuthTrans;
 
     // fill session structure
@@ -85,7 +84,7 @@
     sn->sn.subject = NULL;
     
     // the session needs the current server configuration
-    sn->config = request->connection->listener->cfg; // TODO: ref
+    sn->config = request->connection->listener->cfg;
 
     // add ip to sn->client pblock
     char ip_str[INET_ADDRSTRLEN];
@@ -398,14 +397,22 @@
 }
 
 int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) {
-    // TODO: keep alive
-    close(sn->connection->fd);
+    if(rq->rq.rq_attr.keep_alive) {
+        SessionHandler *sh = sn->connection->session_handler;
+        sh->keep_alive(sh, sn->connection);
+        /*
+         * keep the connection object
+         * the sn->config is referenced by the connection, so we don't
+         * unref the configuration
+         */
+    } else {
+        close(sn->connection->fd);
+        free(sn->connection);
+        cfg_unref(sn->config);
+        // TODO: create connection_close function
+    }
     
-    cfg_unref(sn->config);
-    
-    // free all memory
-    free(sn->connection);
-    
+    // free all memory 
     free(sn->netbuf->inbuf);
     free(sn->netbuf);
     
--- a/src/server/daemon/httprequest.h	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/httprequest.h	Tue Jun 25 22:18:59 2013 +0200
@@ -52,8 +52,6 @@
     sstr_t         httpv;
     HeaderArray    *headers;
     netbuf         *netbuf;
-    NSAPISession   *sn; // TODO: remove
-    NSAPIRequest   *rq; // TODO: remove
 };
 
 struct _header {
--- a/src/server/daemon/protocol.c	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/protocol.c	Tue Jun 25 22:18:59 2013 +0200
@@ -339,7 +339,15 @@
     add_http_response_header(out, rq);
     
     // add connection header
-    sbuf_write(out, "Connection: close\r\n", 19);
+    char *conn_str = pblock_findkeyval(pb_key_connection, rq->headers);
+    if(conn_str && !strcasecmp(conn_str, "keep-alive")) {
+        sbuf_write(out, "Connection: keep-alive\r\n", 24);
+        pblock_kvinsert(pb_key_connection, "keep-alive", 10, rq->srvhdrs);
+        rq->rq_attr.keep_alive = 1;
+    } else {
+        sbuf_write(out, "Connection: close\r\n", 19);
+        pblock_kvinsert(pb_key_connection, "close", 5, rq->srvhdrs);
+    }
 
     // response header end
     sbuf_write(out, "\r\n", 2);
--- a/src/server/daemon/sessionhandler.c	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/sessionhandler.c	Tue Jun 25 22:18:59 2013 +0200
@@ -110,12 +110,18 @@
     return NULL;
 }
 
+void basic_keep_alive(SessionHandler *handler, Connection *conn) {
+    
+}
+
+
 /* ----- 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;
+    handler->sh.keep_alive = evt_keep_alive;
     return (SessionHandler*)handler;
 }
 
@@ -280,3 +286,20 @@
     
     return 0;
 }
+
+void evt_keep_alive(SessionHandler *handler, Connection *conn) {
+    // TODO: set timeout
+    
+    /* TODO:
+     * Don't just re-enqueue the connection
+     * create a evt_req_init function which does most of the evt_enq_conn stuff
+     * but don't poll.
+     * evt_keep_alive should poll and if an event occurs:
+     *   evt_req_init
+     *   evt_request_input
+     * evt_enq_conn should do:
+     *   evt_req_init
+     *   ev_pollin
+     */
+    evt_enq_conn(handler, conn);
+}
--- a/src/server/daemon/sessionhandler.h	Tue Jun 25 15:45:13 2013 +0200
+++ b/src/server/daemon/sessionhandler.h	Tue Jun 25 22:18:59 2013 +0200
@@ -48,8 +48,21 @@
 };
 
 typedef void(*enqueue_connection_f)(SessionHandler*, Connection*);
+typedef void(*keep_alive_f)(SessionHandler*, Connection*);
 struct _session_handler {
-    enqueue_connection_f enqueue_connection;
+    /*
+     * Adds a connection. The session handler starts reading and parsing the
+     * http request. After that its pass the request to the request handler
+     * (handle_request).
+     */
+    void(*enqueue_connection)(SessionHandler *sh, Connection *conn);
+    
+    /*
+     * Adds a connection to the keep-alive handler. The session handler
+     * waits for new data and re-enqueues the connection, if new data is
+     * available
+     */
+    void(*keep_alive)(SessionHandler*, Connection *conn);
 };
 
 /*
@@ -87,6 +100,8 @@
 
 void* basic_run_session(void *data);
 
+void basic_keep_alive(SessionHandler *handler, Connection *conn);
+
 
 SessionHandler* create_event_session_handler();
 
@@ -96,6 +111,8 @@
 int evt_request_finish(event_handler_t *h, event_t *event);
 int evt_request_error(event_handler_t *h, event_t *event);
 
+void evt_keep_alive(SessionHandler *handler, Connection *conn);
+
 
 #ifdef	__cplusplus
 }

mercurial