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