Commit abd69d0a2057d2d52f8794925854a82984d5135c

Authored by Georg Hopp
1 parent dfdfd20d

disconnect on invalid request line

  1 +2012-02-20 07:55:06 +0100 Georg Hopp
  2 +
  3 + * disconnect on invalid request line (HEAD, master)
  4 +
1 5 2012-02-19 20:12:40 +0100 Georg Hopp
2 6
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)
  7 + * 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. (origin/master, origin/HEAD)
4 8
5 9 2012-02-19 18:28:30 +0100 Georg Hopp
6 10
7   - * increase writebuffer size a lot. (origin/master, origin/HEAD)
  11 + * increase writebuffer size a lot.
8 12
9 13 2012-02-19 18:15:55 +0100 Georg Hopp
10 14
... ...
... ... @@ -45,6 +45,7 @@ ssize_t cbufWrite(Cbuf, int fd);
45 45 char * cbufGetLine(Cbuf);
46 46 char * cbufGetData(Cbuf, size_t);
47 47 char * cbufSetData(Cbuf, const void *, size_t);
  48 +void cbufEmpty(Cbuf);
48 49
49 50 char * cbufGetRead(Cbuf this);
50 51 char * cbufGetWrite(Cbuf this);
... ...
... ... @@ -26,6 +26,9 @@ char httpMessageHasKeepAlive(HttpMessage);
26 26 size_t httpMessageHeaderSizeGet(HttpMessage);
27 27 char * httpMessageHeaderToString(HttpMessage, char *);
28 28
  29 +int httpMessageGetVersion(HttpMessage, int *, int *);
  30 +int httpMessageHasValidVersion(HttpMessage);
  31 +
29 32 #endif // __HTTP_MESSAGE__
30 33
31 34 // vim: set ts=4 sw=4:
... ...
... ... @@ -4,6 +4,10 @@
4 4 #include "class.h"
5 5 #include "http/message.h"
6 6
  7 +#define N_HTTP_METHOD 8
  8 +
  9 +char * http_method[N_HTTP_METHOD];
  10 +
7 11 CLASS(HttpRequest) {
8 12 EXTENDS(HttpMessage);
9 13
... ... @@ -11,6 +15,8 @@ CLASS(HttpRequest) {
11 15 char * uri;
12 16 };
13 17
  18 +int httpRequestHasValidMethod(HttpRequest);
  19 +
14 20 #endif /* __HTTP_REQUEST_H__ */
15 21
16 22 // vim: set ts=4 sw=4:
... ...
... ... @@ -13,10 +13,12 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \
13 13 cbuf/get_line.c cbuf/set_data.c cbuf/get_data.c \
14 14 cbuf/addr_index.c cbuf/get_free.c cbuf/get_read.c cbuf/get_write.c \
15 15 cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \
16   - cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c
  16 + cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c \
  17 + cbuf/empty.c
17 18 MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c \
18   - http/message/header_size_get.c http/message/header_to_string.c
19   -REQ = http/request.c
  19 + http/message/header_size_get.c http/message/header_to_string.c \
  20 + http/message/get_version.c http/message/has_valid_version.c
  21 +REQ = http/request.c http/request/has_valid_method.c
20 22 RESP = http/response.c \
21 23 http/response/404.c \
22 24 http/response/image.c \
... ...
  1 +#include "cbuf.h"
  2 +
  3 +void
  4 +cbufEmpty(Cbuf this)
  5 +{
  6 + this->bused = 0;
  7 + this->read = this->write;
  8 +}
  9 +
  10 +// vim: set ts=4 sw=4:
... ...
  1 +#include <string.h>
  2 +#include <stdlib.h>
  3 +
  4 +#include "http/message.h"
  5 +
  6 +int
  7 +httpMessageGetVersion(HttpMessage this, int * major, int * minor)
  8 +{
  9 + char * major_ptr = this->version + 5;
  10 + char * minor_ptr = strchr(major_ptr, '.') + 1;
  11 + char version[] = "\0\0\0";
  12 +
  13 + if (NULL == minor_ptr ||
  14 + ((minor_ptr - major_ptr - 1) > 2) ||
  15 + strlen(minor_ptr) > 2)
  16 + return -1;
  17 +
  18 + memcpy(version, major_ptr, minor_ptr - major_ptr - 1);
  19 + *major = atoi(version);
  20 +
  21 + memset(version, 0, 3);
  22 + strcpy(version, minor_ptr);
  23 + *minor = atoi(version);
  24 +
  25 + return ((*major)<<7)|(*minor);
  26 +}
  27 +
  28 +// vim: set ts=4 sw=4:
... ...
  1 +#include <string.h>
  2 +
  3 +#include "http/message.h"
  4 +
  5 +int
  6 +httpMessageHasValidVersion(HttpMessage this)
  7 +{
  8 + int major;
  9 + int minor;
  10 +
  11 + if (NULL == this->version)
  12 + return 0;
  13 +
  14 + if (8 > strlen(this->version))
  15 + return 0;
  16 +
  17 + if (0 > httpMessageGetVersion(this, &major, &minor))
  18 + return 0;
  19 +
  20 + if (0 != memcmp("HTTP/", this->version, sizeof("HTTP/")-1))
  21 + return 0;
  22 +
  23 + if (1 != major)
  24 + return 0;
  25 +
  26 + if (0 > minor || 1 < minor)
  27 + return 0;
  28 +
  29 + return 1;
  30 +}
  31 +
  32 +// vim: set ts=4 sw=4:
... ...
  1 +#include <string.h>
  2 +
  3 +#include "http/request.h"
  4 +
  5 +char * http_method[N_HTTP_METHOD] = {
  6 + "OPTIONS",
  7 + "GET",
  8 + "HEAD",
  9 + "POST",
  10 + "PUT",
  11 + "DELETE",
  12 + "TRACE",
  13 + "CONNECT"};
  14 +
  15 +int
  16 +httpRequestHasValidMethod(HttpRequest this)
  17 +{
  18 + int i;
  19 +
  20 + if (NULL == this->method)
  21 + return 0;
  22 +
  23 + for (i=0; i<N_HTTP_METHOD; i++) {
  24 + if (0 == strcmp(http_method[i], this->method))
  25 + break;
  26 + }
  27 +
  28 + return (i != N_HTTP_METHOD);
  29 +}
  30 +
  31 +// vim: set ts=4 sw=4:
... ...
... ... @@ -39,57 +39,32 @@ char * method[N_METHODS] = {
39 39 ssize_t
40 40 httpRequestParserGetRequestLine(HttpRequestParser this, char * cr)
41 41 {
42   - HttpRequest request = this->cur_request;
  42 + char * method, * uri, * version;
43 43 HttpMessage message = (HttpMessage)request;
44   - char * space1, * space2;
45   - size_t len = cr - this->buffer->buffer - this->buffer->bstart;
46   - int i;
47 44
48   - space1 = memchr(
49   - this->buffer->buffer + this->buffer->bstart,
50   - ' ', len);
  45 + method = line;
  46 + uri = strchr(line, ' ');
51 47
52   - if (NULL == space1) {
53   - return -1;
54   - }
  48 + if (NULL == uri)
  49 + return;
55 50
56   - len = cr - space1;
57   - space2 = memchr(space1 + 1, ' ', len);
  51 + *uri++ = 0;
  52 + for (; *uri == ' ' && *uri != 0; uri++);
58 53
59   - if (NULL == space2) {
60   - return -1;
61   - }
  54 + version = strchr(uri, ' ');
62 55
63   - len = space1 - this->buffer->buffer - this->buffer->bstart;
64   - request->method = calloc(1, len + 1);
65   - memcpy(request->method,
66   - this->buffer->buffer + this->buffer->bstart,
67   - len);
  56 + if (NULL == version)
  57 + return;
68 58
69   - for (i= 0; i< N_METHODS; i++) {
70   - if (0 == memcmp(method[i], request->method, MIN_SIZE(method[i], len))) {
71   - break;
72   - }
73   - }
  59 + *version++ = 0;
  60 + for (; *version == ' ' && *version != 0; version++);
74 61
75   - if (i == N_METHODS) {
76   - return -1;
77   - }
78   -
79   - len = space2 - space1 - 1;
80   - request->uri = calloc(1, len + 1);
81   - memcpy(request->uri, space1 + 1, len);
82   -
83   - len = cr - space2 - 1;
84   - message->version = calloc(1, len + 1);
85   - memcpy(message->version, space2 + 1, len);
86   -
87   - if (len+1 != sizeof("HTTP/1.1") ||
88   - 0 != memcmp("HTTP/1.", message->version, len-1)) {
89   - return -1;
90   - }
91   -
92   - return 1; //* @TODO: return something useful here
  62 + request->method = malloc(strlen(method) + 1);
  63 + strcpy(request->method, method);
  64 + request->uri = malloc(strlen(uri) + 1);
  65 + strcpy(request->uri, uri);
  66 + message->version = malloc(strlen(version) + 1);
  67 + strcpy(message->version, version);
93 68 }
94 69
95 70 // vim: set ts=4 sw=4:
... ...
... ... @@ -83,18 +83,17 @@ httpRequestParserParse(HttpRequestParser this, int fd)
83 83 break;
84 84 }
85 85
86   - if (0 > httpRequestParserGetRequestLine(this, line_end)) {
87   - ret = -1;
88   - cont = 0;
89   - break;
  86 + httpRequestParserGetRequestLine(this->cur_request, line);
  87 + if (! httpRequestHasValidMethod(this->cur_request)) {
  88 + cbufRelease(this->buffer);
  89 + this->ourLock = FALSE;
  90 + return -1;
90 91 }
91   -
92   - len = line_end - this->buffer->buffer - this->buffer->bstart + 2;
93   - this->buffer->bstart += len;
94   - if (this->buffer->bstart >= this->buffer->bsize) {
95   - this->buffer->bstart -= this->buffer->bsize;
  92 + if (! httpMessageHasValidVersion((HttpMessage)this->cur_request)) {
  93 + cbufRelease(this->buffer);
  94 + this->ourLock = FALSE;
  95 + return -1;
96 96 }
97   - this->buffer->bused -= len;
98 97
99 98 this->state = HTTP_REQUEST_REQUEST_LINE_DONE;
100 99 break;
... ...
Please register or login to post a comment