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 | 2012-02-19 20:12:40 +0100 Georg Hopp | 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 | 2012-02-19 18:28:30 +0100 Georg Hopp | 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 | 2012-02-19 18:15:55 +0100 Georg Hopp | 13 | 2012-02-19 18:15:55 +0100 Georg Hopp |
10 | 14 |
@@ -45,6 +45,7 @@ ssize_t cbufWrite(Cbuf, int fd); | @@ -45,6 +45,7 @@ ssize_t cbufWrite(Cbuf, int fd); | ||
45 | char * cbufGetLine(Cbuf); | 45 | char * cbufGetLine(Cbuf); |
46 | char * cbufGetData(Cbuf, size_t); | 46 | char * cbufGetData(Cbuf, size_t); |
47 | char * cbufSetData(Cbuf, const void *, size_t); | 47 | char * cbufSetData(Cbuf, const void *, size_t); |
48 | +void cbufEmpty(Cbuf); | ||
48 | 49 | ||
49 | char * cbufGetRead(Cbuf this); | 50 | char * cbufGetRead(Cbuf this); |
50 | char * cbufGetWrite(Cbuf this); | 51 | char * cbufGetWrite(Cbuf this); |
@@ -26,6 +26,9 @@ char httpMessageHasKeepAlive(HttpMessage); | @@ -26,6 +26,9 @@ char httpMessageHasKeepAlive(HttpMessage); | ||
26 | size_t httpMessageHeaderSizeGet(HttpMessage); | 26 | size_t httpMessageHeaderSizeGet(HttpMessage); |
27 | char * httpMessageHeaderToString(HttpMessage, char *); | 27 | char * httpMessageHeaderToString(HttpMessage, char *); |
28 | 28 | ||
29 | +int httpMessageGetVersion(HttpMessage, int *, int *); | ||
30 | +int httpMessageHasValidVersion(HttpMessage); | ||
31 | + | ||
29 | #endif // __HTTP_MESSAGE__ | 32 | #endif // __HTTP_MESSAGE__ |
30 | 33 | ||
31 | // vim: set ts=4 sw=4: | 34 | // vim: set ts=4 sw=4: |
@@ -4,6 +4,10 @@ | @@ -4,6 +4,10 @@ | ||
4 | #include "class.h" | 4 | #include "class.h" |
5 | #include "http/message.h" | 5 | #include "http/message.h" |
6 | 6 | ||
7 | +#define N_HTTP_METHOD 8 | ||
8 | + | ||
9 | +char * http_method[N_HTTP_METHOD]; | ||
10 | + | ||
7 | CLASS(HttpRequest) { | 11 | CLASS(HttpRequest) { |
8 | EXTENDS(HttpMessage); | 12 | EXTENDS(HttpMessage); |
9 | 13 | ||
@@ -11,6 +15,8 @@ CLASS(HttpRequest) { | @@ -11,6 +15,8 @@ CLASS(HttpRequest) { | ||
11 | char * uri; | 15 | char * uri; |
12 | }; | 16 | }; |
13 | 17 | ||
18 | +int httpRequestHasValidMethod(HttpRequest); | ||
19 | + | ||
14 | #endif /* __HTTP_REQUEST_H__ */ | 20 | #endif /* __HTTP_REQUEST_H__ */ |
15 | 21 | ||
16 | // vim: set ts=4 sw=4: | 22 | // vim: set ts=4 sw=4: |
@@ -13,10 +13,12 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \ | @@ -13,10 +13,12 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \ | ||
13 | cbuf/get_line.c cbuf/set_data.c cbuf/get_data.c \ | 13 | cbuf/get_line.c cbuf/set_data.c cbuf/get_data.c \ |
14 | cbuf/addr_index.c cbuf/get_free.c cbuf/get_read.c cbuf/get_write.c \ | 14 | cbuf/addr_index.c cbuf/get_free.c cbuf/get_read.c cbuf/get_write.c \ |
15 | cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \ | 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 | MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c \ | 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 | RESP = http/response.c \ | 22 | RESP = http/response.c \ |
21 | http/response/404.c \ | 23 | http/response/404.c \ |
22 | http/response/image.c \ | 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,57 +39,32 @@ char * method[N_METHODS] = { | ||
39 | ssize_t | 39 | ssize_t |
40 | httpRequestParserGetRequestLine(HttpRequestParser this, char * cr) | 40 | httpRequestParserGetRequestLine(HttpRequestParser this, char * cr) |
41 | { | 41 | { |
42 | - HttpRequest request = this->cur_request; | 42 | + char * method, * uri, * version; |
43 | HttpMessage message = (HttpMessage)request; | 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 | // vim: set ts=4 sw=4: | 70 | // vim: set ts=4 sw=4: |
@@ -83,18 +83,17 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -83,18 +83,17 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
83 | break; | 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 | this->state = HTTP_REQUEST_REQUEST_LINE_DONE; | 98 | this->state = HTTP_REQUEST_REQUEST_LINE_DONE; |
100 | break; | 99 | break; |
Please
register
or
login
to post a comment