Commit abd69d0a2057d2d52f8794925854a82984d5135c
1 parent
dfdfd20d
disconnect on invalid request line
Showing
11 changed files
with
149 additions
and
58 deletions
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 | ... | ... |
... | ... | @@ -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 \ | ... | ... |
src/cbuf/empty.c
0 → 100644
src/http/message/get_version.c
0 → 100644
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: | ... | ... |
src/http/message/has_valid_version.c
0 → 100644
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: | ... | ... |
src/http/request/has_valid_method.c
0 → 100644
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