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