# HG changeset patch # User Olaf Wintermann # Date 1372191539 -7200 # Node ID 3578977d29a3ee66ce7120fdc0c1a1cde7bf43c3 # Parent f1cff81e425ad12fe328a6330b60969c94c3ea84 added keep-alive support diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/httplistener.c --- 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; diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/httprequest.c --- 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); diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/httprequest.h --- 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 { diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/protocol.c --- 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); diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/sessionhandler.c --- 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); +} diff -r f1cff81e425a -r 3578977d29a3 src/server/daemon/sessionhandler.h --- 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 }