Commit dfdfd20d8ef631dada26ad835e25d289cb5425e7
1 parent
eae798e5
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.
Showing
4 changed files
with
58 additions
and
3 deletions
| 1 | +2012-02-19 20:12:40 +0100 Georg Hopp | ||
| 2 | + | ||
| 3 | + * 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) | ||
| 4 | + | ||
| 1 | 2012-02-19 18:28:30 +0100 Georg Hopp | 5 | 2012-02-19 18:28:30 +0100 Georg Hopp |
| 2 | 6 | ||
| 3 | - * increase writebuffer size a lot. (HEAD, master) | 7 | + * increase writebuffer size a lot. (origin/master, origin/HEAD) |
| 4 | 8 | ||
| 5 | 2012-02-19 18:15:55 +0100 Georg Hopp | 9 | 2012-02-19 18:15:55 +0100 Georg Hopp |
| 6 | 10 | ||
| 7 | - * 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) | 11 | + * 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. |
| 8 | 12 | ||
| 9 | 2012-02-19 15:41:48 +0100 Georg Hopp | 13 | 2012-02-19 15:41:48 +0100 Georg Hopp |
| 10 | 14 |
| @@ -28,6 +28,9 @@ CLASS(HttpRequestParser) { | @@ -28,6 +28,9 @@ CLASS(HttpRequestParser) { | ||
| 28 | Cbuf buffer; | 28 | Cbuf buffer; |
| 29 | void * ourLock; | 29 | void * ourLock; |
| 30 | 30 | ||
| 31 | + char * incomplete; | ||
| 32 | + size_t isize; | ||
| 33 | + | ||
| 31 | HttpMessageQueue request_queue; | 34 | HttpMessageQueue request_queue; |
| 32 | HttpRequest cur_request; | 35 | HttpRequest cur_request; |
| 33 | 36 |
| @@ -34,6 +34,9 @@ dtor(void * _this) | @@ -34,6 +34,9 @@ dtor(void * _this) | ||
| 34 | if (TRUE == this->ourLock) | 34 | if (TRUE == this->ourLock) |
| 35 | cbufRelease(this->buffer); | 35 | cbufRelease(this->buffer); |
| 36 | 36 | ||
| 37 | + if (NULL != this->incomplete) | ||
| 38 | + free(this->incomplete); | ||
| 39 | + | ||
| 37 | if (NULL != this->cur_request) | 40 | if (NULL != this->cur_request) |
| 38 | delete(&(this->cur_request)); | 41 | delete(&(this->cur_request)); |
| 39 | } | 42 | } |
| @@ -25,7 +25,30 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -25,7 +25,30 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
| 25 | this->ourLock = TRUE; | 25 | this->ourLock = TRUE; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | - if(0 > (read = cbufRead(this->buffer, fd))) { | 28 | + if (NULL != this->incomplete) { |
| 29 | + /** | ||
| 30 | + * i need a way to stop incomplete requests | ||
| 31 | + * from locking the buffer forever. | ||
| 32 | + * Maybe this is the position for this... | ||
| 33 | + * but i must carefully think about the | ||
| 34 | + * conditions...maybe a rewrite of the | ||
| 35 | + * parser is neccessary to detect a | ||
| 36 | + * stale request. | ||
| 37 | + * The problem here seems to be that i can't | ||
| 38 | + * say for sure if the request is stale. | ||
| 39 | + * This is mostly because i work linewise. | ||
| 40 | + * This MUST be accomplished within | ||
| 41 | + * request line and header reads. | ||
| 42 | + * As far as i see the only way it to | ||
| 43 | + * always empty the buffer completely after | ||
| 44 | + * every read and release the buffer then. | ||
| 45 | + */ | ||
| 46 | + cbufSetData(this->buffer, this->incomplete, this->isize); | ||
| 47 | + free(this->incomplete); | ||
| 48 | + this->incomplete = NULL; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + if (0 > (read = cbufRead(this->buffer, fd))) { | ||
| 29 | return read; | 52 | return read; |
| 30 | } | 53 | } |
| 31 | 54 | ||
| @@ -47,6 +70,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -47,6 +70,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
| 47 | 70 | ||
| 48 | case HTTP_REQUEST_START: | 71 | case HTTP_REQUEST_START: |
| 49 | if (NULL == (line = cbufGetLine(this->buffer))) { | 72 | if (NULL == (line = cbufGetLine(this->buffer))) { |
| 73 | + if (! cbufIsEmpty(this->buffer)) { | ||
| 74 | + this->isize = this->buffer->bused; | ||
| 75 | + this->incomplete = malloc(this->isize); | ||
| 76 | + memcpy(this->incomplete, | ||
| 77 | + cbufGetData(this->buffer, this->isize), | ||
| 78 | + this->isize); | ||
| 79 | + } | ||
| 80 | + cbufRelease(this->buffer); | ||
| 81 | + this->ourLock = FALSE; | ||
| 50 | cont = 0; | 82 | cont = 0; |
| 51 | break; | 83 | break; |
| 52 | } | 84 | } |
| @@ -69,6 +101,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -69,6 +101,15 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
| 69 | 101 | ||
| 70 | case HTTP_REQUEST_REQUEST_LINE_DONE: | 102 | case HTTP_REQUEST_REQUEST_LINE_DONE: |
| 71 | if (NULL == (line = cbufGetLine(this->buffer))) { | 103 | if (NULL == (line = cbufGetLine(this->buffer))) { |
| 104 | + if (! cbufIsEmpty(this->buffer)) { | ||
| 105 | + this->isize = this->buffer->bused; | ||
| 106 | + this->incomplete = malloc(this->isize); | ||
| 107 | + memcpy(this->incomplete, | ||
| 108 | + cbufGetData(this->buffer, this->isize), | ||
| 109 | + this->isize); | ||
| 110 | + } | ||
| 111 | + cbufRelease(this->buffer); | ||
| 112 | + this->ourLock = FALSE; | ||
| 72 | cont = 0; | 113 | cont = 0; |
| 73 | break; | 114 | break; |
| 74 | } | 115 | } |
| @@ -100,6 +141,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -100,6 +141,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
| 100 | HttpMessage message = (HttpMessage)this->cur_request; | 141 | HttpMessage message = (HttpMessage)this->cur_request; |
| 101 | 142 | ||
| 102 | httpRequestParserGetBody(this); | 143 | httpRequestParserGetBody(this); |
| 144 | + if (cbufIsEmpty(this->buffer)) { | ||
| 145 | + cbufRelease(this->buffer); | ||
| 146 | + this->ourLock = FALSE; | ||
| 147 | + } | ||
| 103 | 148 | ||
| 104 | if (message->dbody == message->nbody) { | 149 | if (message->dbody == message->nbody) { |
| 105 | this->state = HTTP_REQUEST_DONE; | 150 | this->state = HTTP_REQUEST_DONE; |
Please
register
or
login
to post a comment