# HG changeset patch # User Olaf Wintermann # Date 1357995647 -3600 # Node ID 636e05eb48f6afafc1fedddb211df0f5bcf89c6b # Parent a24aa388f02f135072af09869271d8f0c54ea7dc cleaning up resources after requests diff -r a24aa388f02f -r 636e05eb48f6 Makefile --- a/Makefile Wed Jan 02 16:03:50 2013 +0100 +++ b/Makefile Sat Jan 12 14:00:47 2013 +0100 @@ -43,6 +43,12 @@ @echo "clean build" rm -f -R build +cleanall: + @echo "clean all" + rm -f -R build + rm -f -R work + rm -f config.mk + install: all cd make; $(MAKE) -f install.mk install diff -r a24aa388f02f -r 636e05eb48f6 make/install.mk --- a/make/install.mk Wed Jan 02 16:03:50 2013 +0100 +++ b/make/install.mk Sat Jan 12 14:00:47 2013 +0100 @@ -55,6 +55,6 @@ sed s:%%WS_INSTALL_DIR%%:$(INSTALL_DIR):g ../templates/bin/stopserv.template > $(INSTALL_DIR)/bin/stopserv chmod +x $(INSTALL_DIR)/bin/stopserv sed s:%%WS_INSTALL_DIR%%:$(INSTALL_DIR):g ../templates/bin/reconfig.template > $(INSTALL_DIR)/bin/reconfig - chmod -x $(INSTALL_DIR)/bin/reconfig + chmod +x $(INSTALL_DIR)/bin/reconfig @echo "copy docs" cp -R ../templates/docs $(INSTALL_DIR)/ diff -r a24aa388f02f -r 636e05eb48f6 src/server/config/serverconf.c --- a/src/server/config/serverconf.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/config/serverconf.c Sat Jan 12 14:00:47 2013 +0100 @@ -44,7 +44,7 @@ conf->objects = ucx_map_new(161); conf->obj = NULL; - + int r = cfg_parse_basic_file((ConfigParser*)conf, in); if(r != 0) { // TODO: free @@ -60,7 +60,7 @@ int serverconf_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line){ ServerConfig *conf = p; - + begin->type = cfg_get_line_type(line); switch(begin->type) { case LINE_BEGIN_TAG: { diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/config.c --- a/src/server/daemon/config.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/config.c Sat Jan 12 14:00:47 2013 +0100 @@ -113,7 +113,7 @@ if(serverconf == NULL) { fprintf(stderr, "Cannot load server.conf\n"); } - ServerConfiguration *serverconfig = malloc(sizeof(ServerConfiguration)); + ServerConfiguration *serverconfig = calloc(1, sizeof(ServerConfiguration)); serverconfig->ref = 1; serverconfig->pool = pool_create(); serverconfig->listeners = NULL; @@ -153,7 +153,7 @@ /* horrible error */ return NULL; } - + UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/event.h --- a/src/server/daemon/event.h Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/event.h Sat Jan 12 14:00:47 2013 +0100 @@ -46,6 +46,7 @@ Session *sn; Request *rq; event_func fn; + event_func finish; intptr_t object; int events; void *cookie; diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/event_linux.c --- a/src/server/daemon/event_linux.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/event_linux.c Sat Jan 12 14:00:47 2013 +0100 @@ -116,6 +116,11 @@ if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) { perror("epoll_ctl"); } + + // if set, execute event->finish + if(event->finish) { + event->finish(ev, event); + } } } } diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/event_solaris.c --- a/src/server/daemon/event_solaris.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/event_solaris.c Sat Jan 12 14:00:47 2013 +0100 @@ -112,6 +112,8 @@ if(ev_poll(ev, event)) { perror("port_associate"); } + } else if(event->finish) { + event->finish(ev, event); } } } diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/httplistener.c --- a/src/server/daemon/httplistener.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/httplistener.c Sat Jan 12 14:00:47 2013 +0100 @@ -281,8 +281,8 @@ /* ready for new connection */ - // this acceptor is outdated if(acceptor_exit) { + // this acceptor is outdated break; } } diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/httprequest.c --- a/src/server/daemon/httprequest.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/httprequest.c Sat Jan 12 14:00:47 2013 +0100 @@ -42,8 +42,7 @@ #include "httplistener.h" #include "error.h" -HTTPRequest *http_request_new() { - HTTPRequest *req = malloc(sizeof(HTTPRequest)); +void http_request_init(HTTPRequest *req) { req->connection = NULL; req->uri.ptr = NULL; @@ -54,22 +53,20 @@ hd->alloc = 16; req->headers = hd; - - return req; } int handle_request(HTTPRequest *request, threadpool_t *thrpool) { // handle nsapi request // create pool - request->pool = pool_create(); + pool_handle_t *pool = pool_create(); // create nsapi data structures - NSAPISession *sn = malloc(sizeof(NSAPISession)); + NSAPISession *sn = pool_malloc(pool, sizeof(NSAPISession)); if(sn == NULL) { /* TODO: error */ } - NSAPIRequest *rq = malloc(sizeof(NSAPIRequest)); + NSAPIRequest *rq = pool_malloc(pool, sizeof(NSAPIRequest)); if(rq == NULL) { /* TODO: error */ } @@ -77,9 +74,10 @@ rq->phase = NSAPIAuthTrans; // fill session structure - sn->sys_fd = request->connection->fd; - sn->sn.pool = pool_create(); - sn->sn.csd = stream_new_from_fd(request->connection->fd); + sn->connection = request->connection; + sn->netbuf = request->netbuf; + sn->sn.pool = pool; + sn->sn.csd = stream_new_from_fd(pool, request->connection->fd); sn->sn.client = pblock_create_pool(sn->sn.pool, 8); sn->sn.next = NULL; sn->sn.fill = 1; @@ -88,7 +86,7 @@ // the session needs the current server configuration sn->config = request->connection->listener->cfg; // TODO: ref - /* add ip to sn->client pblock */ + // add ip to sn->client pblock char ip_str[INET_ADDRSTRLEN]; if(inet_ntop( AF_INET, @@ -100,7 +98,7 @@ } // init NSAPI request structure - if(request_initialize(request->pool, request, rq) != 0) { + if(request_initialize(pool, request, rq) != 0) { printf("Cannot initialize request structure\n"); return 1; } @@ -108,9 +106,8 @@ // set default virtual server rq->vs = request->connection->listener->default_vs.vs; - /* Pass request line as "clf-request" */ - /* TODO: with or without \r\n ? */ - // hack to remove \r\n + // Pass request line as "clf-request" + // remove \r\n sstr_t clfreq = request->request_line; while(clfreq.ptr[clfreq.length - 1] < 33) { clfreq.length--; @@ -170,7 +167,7 @@ /* Get abs_path part of request URI, and canonicalize the path */ absPath.ptr = util_canonicalize_uri( - request->pool, + pool, absPath.ptr, absPath.length, (int*)&absPath.length); @@ -202,7 +199,7 @@ ha->headers[i].name[0] += 32; } - /* change to lower case */ + // change to lower case char *header_name = ha->headers[i].name; for(int i=0;header_name[i]!=0;i++) { if(header_name[i] > 64 && header_name[i] < 97) { @@ -216,7 +213,7 @@ rq->rq.headers); } - /* check for request body and prepare input buffer */ + // check for request body and prepare input buffer char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers); if(ctlen_str) { int ctlen = atoi(ctlen_str); @@ -227,14 +224,15 @@ /* create new netbuf */ NetIOStream *net_io = (NetIOStream*)net_stream_from_fd( + pool, request->connection->fd); net_io->max_read = ctlen; - sn->sn.inbuf = malloc(sizeof(netbuf)); + sn->sn.inbuf = pool_malloc(pool, sizeof(netbuf)); sn->sn.inbuf->sd = net_io; sn->sn.inbuf->pos = 0; - /* prepare buffer */ + // prepare buffer int cur_input_len = nb->cursize - nb->pos; if(cur_input_len >= ctlen) { @@ -247,10 +245,10 @@ sn->sn.inbuf->inbuf = nb->inbuf + nb->pos; } else { sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen); - sn->sn.inbuf->inbuf = malloc(sn->sn.inbuf->maxsize); + sn->sn.inbuf->inbuf = pool_malloc(pool, sn->sn.inbuf->maxsize); if(cur_input_len > 0) { - /* we have read a part of the request body -> copy to netbuf */ + // we have read a part of the request body -> copy to netbuf memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len); } @@ -297,6 +295,16 @@ hd->len++; } +void header_array_free(HeaderArray *hd) { + HeaderArray *next; + while(hd) { + next = hd->next; + free(hd->headers); + free(hd); + hd = next; + } +} + /* * NSAPI Processing @@ -383,8 +391,17 @@ } int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) { - // TODO: free memory - close(sn->sys_fd); + // TODO: keep alive + close(sn->connection->fd); + + // free all memory + free(sn->connection); + + free(sn->netbuf->inbuf); + free(sn->netbuf); + + pool_destroy(sn->sn.pool); + return 0; } diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/httprequest.h --- a/src/server/daemon/httprequest.h Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/httprequest.h Sat Jan 12 14:00:47 2013 +0100 @@ -52,9 +52,8 @@ sstr_t httpv; HeaderArray *headers; netbuf *netbuf; - NSAPISession *sn; - NSAPIRequest *rq; - pool_handle_t *pool; + NSAPISession *sn; // TODO: remove + NSAPIRequest *rq; // TODO: remove }; struct _header { @@ -69,7 +68,8 @@ int alloc; }; -HTTPRequest *http_request_new(); +void http_request_init(HTTPRequest *req); +void http_request_cleanup(HTTPRequest *req); /* * starts request processing after reading the request header @@ -82,6 +82,7 @@ void header_add(HeaderArray *hd, char *name, char *value); +void header_array_free(HeaderArray *hd); int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq); int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq); diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/session.c --- a/src/server/daemon/session.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/session.c Sat Jan 12 14:00:47 2013 +0100 @@ -35,7 +35,7 @@ return NULL; } - +// new NSAPI_PUBLIC void* session_get_config(Session *s) { NSAPISession *sn = (NSAPISession*)s; return sn->config; diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/session.h --- a/src/server/daemon/session.h Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/session.h Sat Jan 12 14:00:47 2013 +0100 @@ -32,6 +32,7 @@ #include "../public/nsapi.h" #include "../util/thrpool.h" #include "config.h" +#include "sessionhandler.h" #ifdef __cplusplus extern "C" { @@ -41,7 +42,8 @@ struct NSAPISession { Session sn; /* public session structure */ - int sys_fd; /* system file descriptor */ + Connection *connection; + netbuf *netbuf; threadpool_t *currentpool; threadpool_t *defaultpool; diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/sessionhandler.c --- a/src/server/daemon/sessionhandler.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/sessionhandler.c Sat Jan 12 14:00:47 2013 +0100 @@ -58,8 +58,9 @@ void* basic_run_session(void *data) { Connection *conn = (Connection*)data; - HTTPRequest *request = http_request_new(); - request->connection = conn; + HTTPRequest request; + http_request_init(&request); + request.connection = conn; // read request netbuf *buf = malloc(sizeof(netbuf)); @@ -71,9 +72,9 @@ buf->inbuf = malloc(2048); buf->errmsg = NULL; - request->netbuf = buf; + request.netbuf = buf; - HttpParser *parser = http_parser_new(request); + HttpParser *parser = http_parser_new(&request); int state; int r; r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos); @@ -99,8 +100,9 @@ } // process request - r = handle_request(request, NULL); // TODO: use correct thread pool - + r = handle_request(&request, NULL); // TODO: use correct thread pool + + // TODO: free, see evt_request_finish return NULL; } @@ -115,8 +117,10 @@ } void evt_enq_conn(SessionHandler *handler, Connection *conn) { - HTTPRequest *request = http_request_new(); + HTTPRequest *request = malloc(sizeof(HTTPRequest)); + http_request_init(request); request->connection = conn; + conn->session_handler = handler; // set socket non blocking int flags; @@ -161,6 +165,7 @@ event_t *event = malloc(sizeof(event_t)); event->fn = evt_request_input; + event->finish = evt_request_finish; event->cookie = io; if(ev_pollin(ev, conn->fd, event) != 0) { @@ -211,9 +216,37 @@ perror("Error: evt_request_input: fcntl"); // TODO: critical error } + + /* + * process request + * + * We return 0 to finish request input. The event handler than stops + * polling and executes event->finish (evt_request_input_finish) + */ + return 0; +} + +int evt_request_finish(event_handler_t *h, event_t *event) { + EventHttpIO *io = event->cookie; + HttpParser *parser = io->parser; + HTTPRequest *request = io->request; - // process request - r = handle_request(request, NULL); + int r = handle_request(request, NULL); + // TODO: if r != REQ_PROCEED ... - return 0; // TODO: return before handle_request + /* + * handle_request can return before the request is finished, but it copies + * all important data. We can free request, parser and event + * + * don't free request->netbuf and request->connection + */ + header_array_free(request->headers); + free(request); + + http_parser_free(parser); + + free(io); + free(event); + + return 0; } diff -r a24aa388f02f -r 636e05eb48f6 src/server/daemon/sessionhandler.h --- a/src/server/daemon/sessionhandler.h Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/daemon/sessionhandler.h Sat Jan 12 14:00:47 2013 +0100 @@ -93,6 +93,7 @@ void evt_enq_conn(SessionHandler *handler, Connection *conn); int evt_request_input(event_handler_t *h, event_t *event); +int evt_request_finish(event_handler_t *h, event_t *event); #ifdef __cplusplus diff -r a24aa388f02f -r 636e05eb48f6 src/server/util/io.c --- a/src/server/util/io.c Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/util/io.c Sat Jan 12 14:00:47 2013 +0100 @@ -50,8 +50,8 @@ }; -IOStream* stream_new_from_fd(int fd) { - SystemIOStream *st = malloc(sizeof(SystemIOStream)); +IOStream* stream_new_from_fd(pool_handle_t *pool, int fd) { + SystemIOStream *st = pool_malloc(pool, sizeof(SystemIOStream)); st->st = native_io_funcs; st->fd = fd; return (IOStream*)st; @@ -66,8 +66,8 @@ } -IOStream* net_stream_from_fd(int fd) { - NetIOStream *st = malloc(sizeof(NetIOStream)); +IOStream* net_stream_from_fd(pool_handle_t *pool, int fd) { + NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream)); st->st = net_io_funcs; st->fd = fd; st->max_read = 0; diff -r a24aa388f02f -r 636e05eb48f6 src/server/util/io.h --- a/src/server/util/io.h Wed Jan 02 16:03:50 2013 +0100 +++ b/src/server/util/io.h Sat Jan 12 14:00:47 2013 +0100 @@ -73,13 +73,13 @@ /* system stream */ -IOStream* stream_new_from_fd(int fd); +IOStream* stream_new_from_fd(pool_handle_t *pool, int fd); ssize_t system_write(IOStream *st, void *buf, size_t nbytes); ssize_t system_read(IOStream *st, void *buf, size_t nbytes); /* net stream */ -IOStream* net_stream_from_fd(int fd); +IOStream* net_stream_from_fd(pool_handle_t *pool, int fd); ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes); ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes);