Commit dfdfd20d8ef631dada26ad835e25d289cb5425e7

Authored by Georg Hopp
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.
  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