diff --git a/ChangeLog b/ChangeLog index bd70a6e..8061ada 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,14 @@ +2012-02-19 20:12:40 +0100 Georg Hopp + + * now incomplete requests should no longer block the complete server. Tested with \'echo -en "GET / HTTP\r\nConn" | nc -w 600 localhost 11212\' and then doing requests from my browser. @TODO: cleanup those stuff, check if a not correctly response reading would block the server. (HEAD, master) + 2012-02-19 18:28:30 +0100 Georg Hopp - * increase writebuffer size a lot. (HEAD, master) + * increase writebuffer size a lot. (origin/master, origin/HEAD) 2012-02-19 18:15:55 +0100 Georg Hopp - * fixed the non keep-alive performance issue as well as i lower memory usage by using a single read and write circular buffer for every connection. @TODO: i noticed a server hang while getting large data (my image) with non keep-alive connections. Additionally an incomplete keep-alive request might stop the server now as the lock on the read buffer will not be released. (origin/master, origin/HEAD) + * fixed the non keep-alive performance issue as well as i lower memory usage by using a single read and write circular buffer for every connection. @TODO: i noticed a server hang while getting large data (my image) with non keep-alive connections. Additionally an incomplete keep-alive request might stop the server now as the lock on the read buffer will not be released. 2012-02-19 15:41:48 +0100 Georg Hopp diff --git a/include/http/request/parser.h b/include/http/request/parser.h index 8fa51ff..60cb65e 100644 --- a/include/http/request/parser.h +++ b/include/http/request/parser.h @@ -28,6 +28,9 @@ CLASS(HttpRequestParser) { Cbuf buffer; void * ourLock; + char * incomplete; + size_t isize; + HttpMessageQueue request_queue; HttpRequest cur_request; diff --git a/src/http/request/parser.c b/src/http/request/parser.c index 3a067e2..5fef31d 100644 --- a/src/http/request/parser.c +++ b/src/http/request/parser.c @@ -34,6 +34,9 @@ dtor(void * _this) if (TRUE == this->ourLock) cbufRelease(this->buffer); + if (NULL != this->incomplete) + free(this->incomplete); + if (NULL != this->cur_request) delete(&(this->cur_request)); } diff --git a/src/http/request/parser/parse.c b/src/http/request/parser/parse.c index d24c510..b24bbd0 100644 --- a/src/http/request/parser/parse.c +++ b/src/http/request/parser/parse.c @@ -25,7 +25,30 @@ httpRequestParserParse(HttpRequestParser this, int fd) this->ourLock = TRUE; } - if(0 > (read = cbufRead(this->buffer, fd))) { + if (NULL != this->incomplete) { + /** + * i need a way to stop incomplete requests + * from locking the buffer forever. + * Maybe this is the position for this... + * but i must carefully think about the + * conditions...maybe a rewrite of the + * parser is neccessary to detect a + * stale request. + * The problem here seems to be that i can't + * say for sure if the request is stale. + * This is mostly because i work linewise. + * This MUST be accomplished within + * request line and header reads. + * As far as i see the only way it to + * always empty the buffer completely after + * every read and release the buffer then. + */ + cbufSetData(this->buffer, this->incomplete, this->isize); + free(this->incomplete); + this->incomplete = NULL; + } + + if (0 > (read = cbufRead(this->buffer, fd))) { return read; } @@ -47,6 +70,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) case HTTP_REQUEST_START: if (NULL == (line = cbufGetLine(this->buffer))) { + if (! cbufIsEmpty(this->buffer)) { + this->isize = this->buffer->bused; + this->incomplete = malloc(this->isize); + memcpy(this->incomplete, + cbufGetData(this->buffer, this->isize), + this->isize); + } + cbufRelease(this->buffer); + this->ourLock = FALSE; cont = 0; break; } @@ -69,6 +101,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) case HTTP_REQUEST_REQUEST_LINE_DONE: if (NULL == (line = cbufGetLine(this->buffer))) { + if (! cbufIsEmpty(this->buffer)) { + this->isize = this->buffer->bused; + this->incomplete = malloc(this->isize); + memcpy(this->incomplete, + cbufGetData(this->buffer, this->isize), + this->isize); + } + cbufRelease(this->buffer); + this->ourLock = FALSE; cont = 0; break; } @@ -100,6 +141,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) HttpMessage message = (HttpMessage)this->cur_request; httpRequestParserGetBody(this); + if (cbufIsEmpty(this->buffer)) { + cbufRelease(this->buffer); + this->ourLock = FALSE; + } if (message->dbody == message->nbody) { this->state = HTTP_REQUEST_DONE;