Commit ee6040201e81ed11f1ee8cea198e612e56aaec70
1 parent
95c0d009
moved request parser to generic parser. This is now able to create either a requ…
…est or a response message dependent on the initial message line (version first or last). TODO change constructor of response to use a len parameter for the reason
Showing
15 changed files
with
293 additions
and
177 deletions
@@ -21,11 +21,11 @@ | @@ -21,11 +21,11 @@ | ||
21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | -#ifndef __HTTP_REQUEST_PARSER_H__ | ||
25 | -#define __HTTP_REQUEST_PARSER_H__ | 24 | +#ifndef __HTTP_PARSER_H__ |
25 | +#define __HTTP_PARSER_H__ | ||
26 | 26 | ||
27 | #include "class.h" | 27 | #include "class.h" |
28 | -#include "http/request.h" | 28 | +#include "http/message.h" |
29 | #include "http/message/queue.h" | 29 | #include "http/message/queue.h" |
30 | #include "cbuf.h" | 30 | #include "cbuf.h" |
31 | 31 | ||
@@ -38,36 +38,33 @@ | @@ -38,36 +38,33 @@ | ||
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | 40 | ||
41 | -typedef enum e_HttpRequestState { | ||
42 | - HTTP_REQUEST_GARBAGE=0, | ||
43 | - HTTP_REQUEST_START, | ||
44 | - HTTP_REQUEST_REQUEST_LINE_DONE, | ||
45 | - HTTP_REQUEST_HEADERS_DONE, | ||
46 | - HTTP_REQUEST_DONE | ||
47 | -} HttpRequestState; | 41 | +typedef enum e_HttpMessageState { |
42 | + HTTP_MESSAGE_GARBAGE=0, | ||
43 | + HTTP_MESSAGE_START, | ||
44 | + HTTP_MESSAGE_INTRO_DONE, | ||
45 | + HTTP_MESSAGE_HEADERS_DONE, | ||
46 | + HTTP_MESSAGE_DONE | ||
47 | +} HttpMessageState; | ||
48 | 48 | ||
49 | 49 | ||
50 | -CLASS(HttpRequestParser) { | 50 | +CLASS(HttpParser) { |
51 | Cbuf buffer; | 51 | Cbuf buffer; |
52 | void * ourLock; | 52 | void * ourLock; |
53 | 53 | ||
54 | char * incomplete; | 54 | char * incomplete; |
55 | size_t isize; | 55 | size_t isize; |
56 | 56 | ||
57 | - HttpMessageQueue request_queue; | ||
58 | - HttpRequest cur_request; | 57 | + HttpMessageQueue queue; |
58 | + HttpMessage current; | ||
59 | 59 | ||
60 | - HttpRequestState state; | 60 | + HttpMessageState state; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | -ssize_t httpRequestParserParse(HttpRequestParser, int); | ||
64 | -void httpRequestParserGetBody(HttpRequestParser); | 63 | +ssize_t httpParserParse(void *, int); |
64 | +void httpParserHeader(HttpParser, const char *, const char *); | ||
65 | +void httpParserNewMessage(HttpParser, const char *, const char * lend); | ||
66 | +size_t httpParserBody(HttpParser, const char *, size_t); | ||
65 | 67 | ||
66 | -void httpRequestParserGetRequestLine( | ||
67 | - HttpRequest, const char *, const char *); | ||
68 | -void httpRequestParserGetHeader( | ||
69 | - HttpRequest, const char *, const char *); | ||
70 | - | ||
71 | -#endif // __HTTP_REQUEST_PARSER_H__ | 68 | +#endif // __HTTP_PARSER_H__ |
72 | 69 | ||
73 | // vim: set ts=4 sw=4: | 70 | // vim: set ts=4 sw=4: |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | #include <sys/types.h> | 27 | #include <sys/types.h> |
28 | 28 | ||
29 | #include "class.h" | 29 | #include "class.h" |
30 | -#include "http/request/parser.h" | 30 | +#include "http/parser.h" |
31 | #include "http/response/writer.h" | 31 | #include "http/response/writer.h" |
32 | #include "cbuf.h" | 32 | #include "cbuf.h" |
33 | 33 | ||
@@ -49,13 +49,10 @@ CLASS(HttpWorker) { | @@ -49,13 +49,10 @@ CLASS(HttpWorker) { | ||
49 | Cbuf pbuf; | 49 | Cbuf pbuf; |
50 | Cbuf wbuf; | 50 | Cbuf wbuf; |
51 | 51 | ||
52 | - HttpRequestParser parser; | 52 | + HttpParser parser; |
53 | HttpResponseWriter writer; | 53 | HttpResponseWriter writer; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | -ssize_t httpWorkerProcess(HttpWorker, int); | ||
57 | -ssize_t httpWorkerWrite(HttpWorker, int); | ||
58 | - | ||
59 | #endif // __HTTP_WORKER_H__ | 56 | #endif // __HTTP_WORKER_H__ |
60 | 57 | ||
61 | // vim: set ts=4 sw=4: | 58 | // vim: set ts=4 sw=4: |
include/utils/http.h
0 → 100644
1 | +#ifndef __UTILS_HTTP_H__ | ||
2 | +#define __UTILS_HTTP_H__ | ||
3 | + | ||
4 | +#include <sys/types.h> | ||
5 | + | ||
6 | +#include "http/message.h" | ||
7 | + | ||
8 | +char isHttpVersion(const char *, size_t); | ||
9 | +HttpMessage httpGetMessage( | ||
10 | + const char *, size_t, | ||
11 | + const char *, size_t, | ||
12 | + const char *, size_t); | ||
13 | + | ||
14 | +#endif // __UTILS_HTTP_H__ | ||
15 | + | ||
16 | +// vim: set ts=4 sw=4: |
@@ -14,24 +14,38 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \ | @@ -14,24 +14,38 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \ | ||
14 | cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \ | 14 | cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \ |
15 | cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c \ | 15 | cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c \ |
16 | cbuf/empty.c | 16 | cbuf/empty.c |
17 | -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 | - http/message/get_version.c http/message/has_valid_version.c | ||
20 | -REQ = http/request.c http/request/has_valid_method.c | 17 | +MSG = http/message.c \ |
18 | + http/message/has_keep_alive.c \ | ||
19 | + http/message/header_size_get.c \ | ||
20 | + http/message/header_to_string.c \ | ||
21 | + http/message/get_version.c \ | ||
22 | + http/message/has_valid_version.c | ||
23 | +MSGQ = http/message/queue.c | ||
24 | +REQ = http/request.c \ | ||
25 | + http/request/has_valid_method.c | ||
21 | RESP = http/response.c \ | 26 | RESP = http/response.c \ |
22 | http/response/304.c \ | 27 | http/response/304.c \ |
23 | http/response/404.c \ | 28 | http/response/404.c \ |
24 | http/response/asset.c \ | 29 | http/response/asset.c \ |
25 | http/response/me.c | 30 | http/response/me.c |
26 | -WORKER = http/worker.c http/worker/process.c http/worker/write.c \ | ||
27 | - http/worker/get_asset.c http/worker/add_common_header.c | 31 | +PARSER = http/parser.c \ |
32 | + http/parser/parse.c \ | ||
33 | + http/parser/new_message.c \ | ||
34 | + http/parser/header.c \ | ||
35 | + http/parser/body.c | ||
36 | +WORKER = http/worker.c \ | ||
37 | + http/worker/process.c \ | ||
38 | + http/worker/write.c \ | ||
39 | + http/worker/get_asset.c \ | ||
40 | + http/worker/add_common_header.c | ||
28 | WRITER = http/response/writer.c http/response/writer/write.c | 41 | WRITER = http/response/writer.c http/response/writer/write.c |
29 | HEADER = http/header.c http/header/get.c http/header/add.c \ | 42 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
30 | http/header/to_string.c | 43 | http/header/to_string.c |
31 | -PARSER = http/request/parser.c http/request/parser/get_header.c \ | ||
32 | - http/request/parser/parse.c http/request/parser/get_request_line.c \ | ||
33 | - http/request/parser/get_body.c | ||
34 | -UTILS = utils/hash.c utils/memory.c utils/daemonize.c utils/signalHandling.c | 44 | +UTILS = utils/hash.c \ |
45 | + utils/memory.c \ | ||
46 | + utils/http.c \ | ||
47 | + utils/daemonize.c \ | ||
48 | + utils/signalHandling.c | ||
35 | 49 | ||
36 | 50 | ||
37 | AM_CFLAGS = -Wall -I ../include/ | 51 | AM_CFLAGS = -Wall -I ../include/ |
@@ -41,6 +55,6 @@ bin_PROGRAMS = testserver | @@ -41,6 +55,6 @@ bin_PROGRAMS = testserver | ||
41 | testserver_SOURCES = testserver.c \ | 55 | testserver_SOURCES = testserver.c \ |
42 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ | 56 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ |
43 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ | 57 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ |
44 | - $(UTILS) | 58 | + $(UTILS) $(MSGQ) |
45 | testserver_CFLAGS = -Wall -I ../include/ | 59 | testserver_CFLAGS = -Wall -I ../include/ |
46 | testserver_LDFLAGS = -lrt | 60 | testserver_LDFLAGS = -lrt |
@@ -28,6 +28,13 @@ | @@ -28,6 +28,13 @@ | ||
28 | #include "http/request.h" | 28 | #include "http/request.h" |
29 | #include "http/header.h" | 29 | #include "http/header.h" |
30 | 30 | ||
31 | +#ifndef TRUE | ||
32 | +#define TRUE 1 | ||
33 | +#endif | ||
34 | + | ||
35 | +#ifndef FALSE | ||
36 | +#define FALSE 0 | ||
37 | +#endif | ||
31 | 38 | ||
32 | char | 39 | char |
33 | httpMessageHasKeepAlive(HttpMessage message) | 40 | httpMessageHasKeepAlive(HttpMessage message) |
@@ -35,7 +42,6 @@ httpMessageHasKeepAlive(HttpMessage message) | @@ -35,7 +42,6 @@ httpMessageHasKeepAlive(HttpMessage message) | ||
35 | HttpHeader header; | 42 | HttpHeader header; |
36 | size_t size; | 43 | size_t size; |
37 | char * value; | 44 | char * value; |
38 | - char * keep_alive = "keep-alive"; | ||
39 | 45 | ||
40 | header = httpHeaderGet( | 46 | header = httpHeaderGet( |
41 | &(message->header), | 47 | &(message->header), |
@@ -46,21 +52,10 @@ httpMessageHasKeepAlive(HttpMessage message) | @@ -46,21 +52,10 @@ httpMessageHasKeepAlive(HttpMessage message) | ||
46 | return 0; | 52 | return 0; |
47 | } | 53 | } |
48 | 54 | ||
49 | - if ((sizeof("keep-alive")-1) != (header->nvalue)[0]) { | ||
50 | - return 0; | ||
51 | - } | ||
52 | - | ||
53 | size = (header->nvalue)[0]; | 55 | size = (header->nvalue)[0]; |
54 | value = (header->value)[0]; | 56 | value = (header->value)[0]; |
55 | 57 | ||
56 | - for (; 0 < size && tolower(*value) == *keep_alive; | ||
57 | - size--, value++, keep_alive++); | ||
58 | - | ||
59 | - if (0 == size) { | ||
60 | - return 1; | ||
61 | - } | ||
62 | - | ||
63 | - return 0; | 58 | + return (0 == strncasecmp("keep-alive", value, size))? 1 : 0; |
64 | } | 59 | } |
65 | 60 | ||
66 | // vim: set ts=4 sw=4: | 61 | // vim: set ts=4 sw=4: |
@@ -23,6 +23,7 @@ | @@ -23,6 +23,7 @@ | ||
23 | #include <string.h> | 23 | #include <string.h> |
24 | 24 | ||
25 | #include "http/message.h" | 25 | #include "http/message.h" |
26 | +#include "utils/http.h" | ||
26 | 27 | ||
27 | int | 28 | int |
28 | httpMessageHasValidVersion(HttpMessage this) | 29 | httpMessageHasValidVersion(HttpMessage this) |
@@ -30,18 +31,12 @@ httpMessageHasValidVersion(HttpMessage this) | @@ -30,18 +31,12 @@ httpMessageHasValidVersion(HttpMessage this) | ||
30 | int major; | 31 | int major; |
31 | int minor; | 32 | int minor; |
32 | 33 | ||
33 | - if (NULL == this->version) | ||
34 | - return 0; | ||
35 | - | ||
36 | - if (8 > strlen(this->version)) | 34 | + if (! isHttpVersion(this->version, strlen(this->version))) |
37 | return 0; | 35 | return 0; |
38 | 36 | ||
39 | if (0 > httpMessageGetVersion(this, &major, &minor)) | 37 | if (0 > httpMessageGetVersion(this, &major, &minor)) |
40 | return 0; | 38 | return 0; |
41 | 39 | ||
42 | - if (0 != memcmp("HTTP/", this->version, sizeof("HTTP/")-1)) | ||
43 | - return 0; | ||
44 | - | ||
45 | if (1 != major) | 40 | if (1 != major) |
46 | return 0; | 41 | return 0; |
47 | 42 |
@@ -28,9 +28,10 @@ | @@ -28,9 +28,10 @@ | ||
28 | #include "interface/class.h" | 28 | #include "interface/class.h" |
29 | #include "interface/stream_reader.h" | 29 | #include "interface/stream_reader.h" |
30 | 30 | ||
31 | -#include "http/request/parser.h" | 31 | +#include "http/parser.h" |
32 | #include "http/message/queue.h" | 32 | #include "http/message/queue.h" |
33 | #include "http/request.h" | 33 | #include "http/request.h" |
34 | +#include "http/response.h" | ||
34 | #include "cbuf.h" | 35 | #include "cbuf.h" |
35 | 36 | ||
36 | #include "utils/memory.h" | 37 | #include "utils/memory.h" |
@@ -38,33 +39,38 @@ | @@ -38,33 +39,38 @@ | ||
38 | 39 | ||
39 | static | 40 | static |
40 | int | 41 | int |
41 | -requestParserCtor(void * _this, va_list * params) | 42 | +httpParserCtor(void * _this, va_list * params) |
42 | { | 43 | { |
43 | - HttpRequestParser this = _this; | 44 | + HttpParser this = _this; |
44 | 45 | ||
45 | - this->buffer = va_arg(* params, Cbuf); | ||
46 | - this->request_queue = new(HttpMessageQueue); | 46 | + this->buffer = va_arg(* params, Cbuf); |
47 | + | ||
48 | + if (NULL == this->buffer) { | ||
49 | + return -1; | ||
50 | + } | ||
51 | + | ||
52 | + this->queue = new(HttpMessageQueue); | ||
47 | 53 | ||
48 | return 0; | 54 | return 0; |
49 | } | 55 | } |
50 | 56 | ||
51 | static | 57 | static |
52 | void | 58 | void |
53 | -requestParserDtor(void * _this) | 59 | +httpParserDtor(void * _this) |
54 | { | 60 | { |
55 | - HttpRequestParser this = _this; | 61 | + HttpParser this = _this; |
56 | 62 | ||
57 | - delete(this->request_queue); | 63 | + delete(this->queue); |
58 | 64 | ||
59 | if (TRUE == this->ourLock) | 65 | if (TRUE == this->ourLock) |
60 | cbufRelease(this->buffer); | 66 | cbufRelease(this->buffer); |
61 | 67 | ||
62 | FREE(this->incomplete); | 68 | FREE(this->incomplete); |
63 | - delete(this->cur_request); | 69 | + delete(this->current); |
64 | } | 70 | } |
65 | 71 | ||
66 | -INIT_IFACE(Class, requestParserCtor, requestParserDtor, NULL); | ||
67 | -INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserParse); | ||
68 | -CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader)); | 72 | +INIT_IFACE(Class, httpParserCtor, httpParserDtor, NULL); |
73 | +INIT_IFACE(StreamReader, httpParserParse); | ||
74 | +CREATE_CLASS(HttpParser, NULL, IFACE(Class), IFACE(StreamReader)); | ||
69 | 75 | ||
70 | // vim: set ts=4 sw=4: | 76 | // vim: set ts=4 sw=4: |
@@ -20,31 +20,31 @@ | @@ -20,31 +20,31 @@ | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | -#include <string.h> | 23 | +#include <stdlib.h> |
24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
25 | 25 | ||
26 | -#include "class.h" | ||
27 | -#include "interface/class.h" | ||
28 | #include "http/header.h" | 26 | #include "http/header.h" |
29 | #include "http/message.h" | 27 | #include "http/message.h" |
30 | -#include "http/request/parser.h" | ||
31 | -#include "ringbuffer.h" | ||
32 | - | ||
33 | -void | ||
34 | -httpRequestParserGetHeader( | ||
35 | - HttpMessage message, | ||
36 | - const char * line, | ||
37 | - const char * line_end) | 28 | +#include "http/parser.h" |
29 | +#include "cbuf.h" | ||
30 | + | ||
31 | +#define MAX(a,b) (((a) > (b))? (a) : (b)) | ||
32 | + | ||
33 | +size_t | ||
34 | +httpParserBody(HttpParser this, const char * buf, size_t nbuf) | ||
38 | { | 35 | { |
39 | - const char * name = line; | ||
40 | - char * value = memchr(line, ':', line_end - line); | ||
41 | - size_t nname = (value++) - name; | 36 | + size_t len = 0; |
37 | + HttpMessage current = this->current; | ||
38 | + | ||
39 | + if (current->dbody < current->nbody) { | ||
40 | + len = MAX(current->nbody - current->dbody, nbuf); | ||
41 | + | ||
42 | + memcpy(current->body, buf, len); | ||
42 | 43 | ||
43 | - for (; *value == ' ' && *value != 0; value++); | 44 | + current->dbody += len; |
45 | + } | ||
44 | 46 | ||
45 | - httpHeaderAdd( | ||
46 | - &(message->header), | ||
47 | - new(HttpHeader, name, nname, value, line_end - value)); | 47 | + return len; |
48 | } | 48 | } |
49 | 49 | ||
50 | // vim: set ts=4 sw=4: | 50 | // vim: set ts=4 sw=4: |
@@ -21,14 +21,14 @@ | @@ -21,14 +21,14 @@ | ||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | +#include <string.h> | ||
25 | +#include <sys/types.h> | ||
24 | 26 | ||
27 | +#include "class.h" | ||
28 | +#include "interface/class.h" | ||
25 | #include "http/header.h" | 29 | #include "http/header.h" |
30 | +#include "http/parser.h" | ||
26 | #include "http/message.h" | 31 | #include "http/message.h" |
27 | -#include "http/request/parser.h" | ||
28 | -#include "cbuf.h" | ||
29 | - | ||
30 | -#define MAX(a,b) (((a) > (b))? (a) : (b)) | ||
31 | - | ||
32 | 32 | ||
33 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) | 33 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
34 | 34 | ||
@@ -37,41 +37,38 @@ | @@ -37,41 +37,38 @@ | ||
37 | * @TODO: not final...input buffer handling not final | 37 | * @TODO: not final...input buffer handling not final |
38 | */ | 38 | */ |
39 | void | 39 | void |
40 | -httpRequestParserGetBody(HttpRequestParser this) | 40 | +httpParserHeader( |
41 | + HttpParser this, | ||
42 | + const char * line, | ||
43 | + const char * lend) | ||
41 | { | 44 | { |
42 | - HttpMessage message = (HttpMessage)(this->cur_request); | ||
43 | - size_t len; | 45 | + const char * name = line; |
46 | + char * value = memchr(line, ':', lend - line); | ||
47 | + size_t nname = (value++) - name; | ||
48 | + HttpMessage current = this->current; | ||
44 | 49 | ||
45 | - if (0 == message->nbody) { | ||
46 | - HttpHeader clen = httpHeaderGet( | ||
47 | - &(message->header), | ||
48 | - "Content-Length", | ||
49 | - sizeof("Content-Length")-1); | ||
50 | - | ||
51 | - if (NULL == clen) { | ||
52 | - this->state = HTTP_REQUEST_DONE; | ||
53 | - return; | ||
54 | - } | ||
55 | - else { | ||
56 | - message->type = HTTP_MESSAGE_BUFFERED; | ||
57 | - message->nbody = atoi((clen->value)[0]); | ||
58 | - if (0 < message->nbody) { | ||
59 | - message->body = malloc(message->nbody); | ||
60 | - } | ||
61 | - message->dbody = 0; | ||
62 | - } | 50 | + if (NULL == value) { |
51 | + return; | ||
63 | } | 52 | } |
64 | this->buffer->bused -= len; | 53 | this->buffer->bused -= len; |
65 | 54 | ||
66 | - if (message->dbody < message->nbody) { | ||
67 | - len = MAX( | ||
68 | - message->nbody - message->dbody, | ||
69 | - this->buffer->bused); | 55 | + for (; *value == ' ' && value < lend; value++); |
70 | 56 | ||
71 | - memcpy(message->body, cbufGetData(this->buffer, len), len); | 57 | + if (value == lend) { |
58 | + return; | ||
59 | + } | ||
72 | 60 | ||
73 | - message->dbody += len; | 61 | + if (0 == strncasecmp("content-length", name, nname-1)) { |
62 | + current->nbody = strtoul(value, NULL, 10); | ||
63 | + if (0 < this->current->nbody) { | ||
64 | + current->body = malloc(current->nbody); | ||
65 | + } | ||
66 | + current->dbody = 0; | ||
74 | } | 67 | } |
68 | + | ||
69 | + httpHeaderAdd( | ||
70 | + &(current->header), | ||
71 | + new(HttpHeader, name, nname, value, lend - value)); | ||
75 | } | 72 | } |
76 | 73 | ||
77 | // vim: set ts=4 sw=4: | 74 | // vim: set ts=4 sw=4: |
src/http/parser/new_message.c
0 → 100644
1 | +#include "http/parser.h" | ||
2 | + | ||
3 | +#include "utils/http.h" | ||
4 | + | ||
5 | +void | ||
6 | +httpParserNewMessage( | ||
7 | + HttpParser this, | ||
8 | + const char * line, | ||
9 | + const char * lend) | ||
10 | +{ | ||
11 | + const char * part1, * part2, * part3; | ||
12 | + size_t len1, len2, len3; | ||
13 | + | ||
14 | + part1 = line; | ||
15 | + part2 = memchr(line, ' ', lend - line); | ||
16 | + | ||
17 | + if (NULL == part2) return; | ||
18 | + | ||
19 | + len1 = part2 - part1; | ||
20 | + for (; *part2 == ' ' && *part2 != 0; part2++); | ||
21 | + | ||
22 | + part3 = memchr(part2, ' ', lend - part2); | ||
23 | + | ||
24 | + if (NULL == part3) return; | ||
25 | + | ||
26 | + len2 = part3 - part2; | ||
27 | + for (; *part3 == ' ' && *part3 != 0; part3++); | ||
28 | + | ||
29 | + len3 = lend - part3; | ||
30 | + | ||
31 | + this->current = httpGetMessage(part1, len1, part2, len2, part3, len3); | ||
32 | +} | ||
33 | + | ||
34 | +// vim: set ts=4 sw=4: |
@@ -22,19 +22,19 @@ | @@ -22,19 +22,19 @@ | ||
22 | 22 | ||
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | 24 | ||
25 | -#include "http/request.h" | ||
26 | -#include "http/message.h" | ||
27 | -#include "http/request/parser.h" | 25 | +#include "http/parser.h" |
28 | #include "interface/class.h" | 26 | #include "interface/class.h" |
27 | +#include "interface/http_intro.h" | ||
29 | #include "cbuf.h" | 28 | #include "cbuf.h" |
30 | 29 | ||
31 | ssize_t | 30 | ssize_t |
32 | -httpRequestParserParse(HttpRequestParser this, int fd) | 31 | +httpParserParse(void * _this, int fd) |
33 | { | 32 | { |
34 | - int cont = 1; | ||
35 | - ssize_t read; | ||
36 | - char * line; | ||
37 | - char * line_end; | 33 | + HttpParser this = _this; |
34 | + int cont = 1; | ||
35 | + ssize_t read; | ||
36 | + char * line; | ||
37 | + char * line_end; | ||
38 | 38 | ||
39 | if (cbufIsLocked(this->buffer)) { | 39 | if (cbufIsLocked(this->buffer)) { |
40 | if (FALSE == this->ourLock) | 40 | if (FALSE == this->ourLock) |
@@ -57,11 +57,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -57,11 +57,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
57 | 57 | ||
58 | while (cont) { | 58 | while (cont) { |
59 | switch(this->state) { | 59 | switch(this->state) { |
60 | - case HTTP_REQUEST_GARBAGE: | 60 | + case HTTP_MESSAGE_GARBAGE: |
61 | cbufSkipNonAlpha(this->buffer); | 61 | cbufSkipNonAlpha(this->buffer); |
62 | if (! cbufIsEmpty(this->buffer)) { | 62 | if (! cbufIsEmpty(this->buffer)) { |
63 | - this->cur_request = new(HttpRequest); | ||
64 | - this->state = HTTP_REQUEST_START; | 63 | + this->state = HTTP_MESSAGE_START; |
65 | } | 64 | } |
66 | else { | 65 | else { |
67 | cbufRelease(this->buffer); | 66 | cbufRelease(this->buffer); |
@@ -71,7 +70,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -71,7 +70,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
71 | 70 | ||
72 | break; | 71 | break; |
73 | 72 | ||
74 | - case HTTP_REQUEST_START: | 73 | + case HTTP_MESSAGE_START: |
75 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { | 74 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { |
76 | if (! cbufIsEmpty(this->buffer)) { | 75 | if (! cbufIsEmpty(this->buffer)) { |
77 | this->isize = this->buffer->bused; | 76 | this->isize = this->buffer->bused; |
@@ -86,22 +85,17 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -86,22 +85,17 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
86 | break; | 85 | break; |
87 | } | 86 | } |
88 | 87 | ||
89 | - httpRequestParserGetRequestLine(this->cur_request, line, line_end); | ||
90 | - if (! httpRequestHasValidMethod(this->cur_request)) { | ||
91 | - cbufRelease(this->buffer); | ||
92 | - this->ourLock = FALSE; | ||
93 | - return -1; | ||
94 | - } | ||
95 | - if (! httpMessageHasValidVersion((HttpMessage)this->cur_request)) { | 88 | + httpParserNewMessage(this, line, line_end); |
89 | + if (NULL == this->current) { | ||
96 | cbufRelease(this->buffer); | 90 | cbufRelease(this->buffer); |
97 | this->ourLock = FALSE; | 91 | this->ourLock = FALSE; |
98 | return -1; | 92 | return -1; |
99 | } | 93 | } |
100 | 94 | ||
101 | - this->state = HTTP_REQUEST_REQUEST_LINE_DONE; | 95 | + this->state = HTTP_MESSAGE_INTRO_DONE; |
102 | break; | 96 | break; |
103 | 97 | ||
104 | - case HTTP_REQUEST_REQUEST_LINE_DONE: | 98 | + case HTTP_MESSAGE_INTRO_DONE: |
105 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { | 99 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { |
106 | if (! cbufIsEmpty(this->buffer)) { | 100 | if (! cbufIsEmpty(this->buffer)) { |
107 | this->isize = this->buffer->bused; | 101 | this->isize = this->buffer->bused; |
@@ -116,46 +110,45 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -116,46 +110,45 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
116 | break; | 110 | break; |
117 | } | 111 | } |
118 | 112 | ||
119 | - if (0 == line_end - this->buffer->buffer - this->buffer->bstart) { | ||
120 | - this->buffer->bstart += 2; | ||
121 | - if (this->buffer->bstart >= this->buffer->bsize) { | ||
122 | - this->buffer->bstart -= this->buffer->bsize; | ||
123 | - } | ||
124 | - this->buffer->bused -= 2; | ||
125 | - | ||
126 | - this->state = HTTP_REQUEST_HEADERS_DONE; | 113 | + if (0 == strlen(line)) { |
114 | + this->state = HTTP_MESSAGE_HEADERS_DONE; | ||
127 | break; | 115 | break; |
128 | } | 116 | } |
129 | 117 | ||
130 | - httpRequestParserGetHeader(this->cur_request, line, line_end); | 118 | + httpParserHeader(this->current, line, line_end); |
131 | break; | 119 | break; |
132 | 120 | ||
133 | - case HTTP_REQUEST_HEADERS_DONE: | 121 | + case HTTP_MESSAGE_HEADERS_DONE: |
134 | { | 122 | { |
135 | - HttpMessage message = (HttpMessage)this->cur_request; | 123 | + cbufIncRead( |
124 | + this->buffer, | ||
125 | + httpParserBody( | ||
126 | + this, | ||
127 | + cbufGetRead(this->buffer), | ||
128 | + this->buffer->bused)); | ||
136 | 129 | ||
137 | - httpRequestParserGetBody(this); | ||
138 | if (cbufIsEmpty(this->buffer)) { | 130 | if (cbufIsEmpty(this->buffer)) { |
139 | cbufRelease(this->buffer); | 131 | cbufRelease(this->buffer); |
140 | this->ourLock = FALSE; | 132 | this->ourLock = FALSE; |
141 | } | 133 | } |
142 | 134 | ||
143 | - if (message->dbody == message->nbody) { | ||
144 | - this->state = HTTP_REQUEST_DONE; | 135 | + if (this->current->dbody == this->current->nbody) { |
136 | + this->state = HTTP_MESSAGE_DONE; | ||
145 | } | 137 | } |
146 | } | 138 | } |
147 | break; | 139 | break; |
148 | 140 | ||
149 | - case HTTP_REQUEST_DONE: | ||
150 | - this->request_queue->msgs[(this->request_queue->nmsgs)++] = | ||
151 | - (HttpMessage)this->cur_request; | ||
152 | - | ||
153 | - this->cur_request = NULL; | 141 | + case HTTP_MESSAGE_DONE: |
142 | + /** | ||
143 | + * enqueue current request | ||
144 | + */ | ||
145 | + this->queue->msgs[(this->queue->nmsgs)++] = this->current; | ||
146 | + this->current = NULL; | ||
154 | 147 | ||
155 | /** | 148 | /** |
156 | * prepare for next request | 149 | * prepare for next request |
157 | */ | 150 | */ |
158 | - this->state = HTTP_REQUEST_GARBAGE; | 151 | + this->state = HTTP_MESSAGE_GARBAGE; |
159 | 152 | ||
160 | break; | 153 | break; |
161 | 154 | ||
@@ -164,7 +157,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) | @@ -164,7 +157,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) | ||
164 | } | 157 | } |
165 | } | 158 | } |
166 | 159 | ||
167 | - return ret; | 160 | + return this->queue->nmsgs; |
168 | } | 161 | } |
169 | 162 | ||
170 | // vim: set ts=4 sw=4: | 163 | // vim: set ts=4 sw=4: |
@@ -37,10 +37,25 @@ static | @@ -37,10 +37,25 @@ static | ||
37 | int | 37 | int |
38 | httpRequestCtor(void * _this, va_list * params) | 38 | httpRequestCtor(void * _this, va_list * params) |
39 | { | 39 | { |
40 | - /** | ||
41 | - * the parent is not called by intention. All infomations | ||
42 | - * are read from the request stream. | ||
43 | - */ | 40 | + HttpRequest this = _this; |
41 | + char * method, * uri; | ||
42 | + size_t mlen, ulen; | ||
43 | + | ||
44 | + method = va_arg(* params, char *); | ||
45 | + mlen = va_arg(* params, size_t); | ||
46 | + uri = va_arg(* params, char *); | ||
47 | + ulen = va_arg(* params, size_t); | ||
48 | + | ||
49 | + PARENTCALL(_this, Class, ctor, params); | ||
50 | + | ||
51 | + this->method = malloc(mlen + 1); | ||
52 | + this->method[mlen] = 0; | ||
53 | + memcpy(this->method, method, mlen); | ||
54 | + | ||
55 | + this->uri = malloc(ulen + 1); | ||
56 | + this->uri[ulen] = 0; | ||
57 | + memcpy(this->uri, uri, ulen); | ||
58 | + | ||
44 | return 0; | 59 | return 0; |
45 | } | 60 | } |
46 | 61 |
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | 6 | ||
7 | #include "class.h" | 7 | #include "class.h" |
8 | #include "http/worker.h" | 8 | #include "http/worker.h" |
9 | -#include "http/request/parser.h" | 9 | +#include "http/parser.h" |
10 | #include "http/response/writer.h" | 10 | #include "http/response/writer.h" |
11 | 11 | ||
12 | #include "interface/class.h" | 12 | #include "interface/class.h" |
@@ -34,7 +34,7 @@ httpWorkerCtor(void * _this, va_list * params) | @@ -34,7 +34,7 @@ httpWorkerCtor(void * _this, va_list * params) | ||
34 | sprintf(cbuf_id, "%s_%s", "writer", id); | 34 | sprintf(cbuf_id, "%s_%s", "writer", id); |
35 | this->wbuf = new(Cbuf, cbuf_id, RESPONSE_WRITER_MAX_BUF); | 35 | this->wbuf = new(Cbuf, cbuf_id, RESPONSE_WRITER_MAX_BUF); |
36 | 36 | ||
37 | - this->parser = new(HttpRequestParser, this->pbuf); | 37 | + this->parser = new(HttpParser, this->pbuf); |
38 | this->writer = new(HttpResponseWriter, this->wbuf); | 38 | this->writer = new(HttpResponseWriter, this->wbuf); |
39 | 39 | ||
40 | return 0; | 40 | return 0; |
@@ -67,13 +67,16 @@ _clone(void * _this, void * _base) | @@ -67,13 +67,16 @@ _clone(void * _this, void * _base) | ||
67 | this->pbuf = NULL; | 67 | this->pbuf = NULL; |
68 | this->wbuf = NULL; | 68 | this->wbuf = NULL; |
69 | 69 | ||
70 | - this->parser = new(HttpRequestParser, base->pbuf); | 70 | + this->parser = new(HttpParser, base->pbuf); |
71 | this->writer = new(HttpResponseWriter, base->wbuf); | 71 | this->writer = new(HttpResponseWriter, base->wbuf); |
72 | } | 72 | } |
73 | 73 | ||
74 | +ssize_t httpWorkerProcess(void *, int); | ||
75 | +ssize_t httpWorkerWrite(void *, int); | ||
76 | + | ||
74 | INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, _clone); | 77 | INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, _clone); |
75 | -INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpWorkerProcess); | ||
76 | -INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpWorkerWrite); | 78 | +INIT_IFACE(StreamReader, httpWorkerProcess); |
79 | +INIT_IFACE(StreamWriter, httpWorkerWrite); | ||
77 | CREATE_CLASS( | 80 | CREATE_CLASS( |
78 | HttpWorker, | 81 | HttpWorker, |
79 | NULL, | 82 | NULL, |
@@ -29,10 +29,7 @@ | @@ -29,10 +29,7 @@ | ||
29 | #include "http/message.h" | 29 | #include "http/message.h" |
30 | #include "http/request.h" | 30 | #include "http/request.h" |
31 | #include "http/message/queue.h" | 31 | #include "http/message/queue.h" |
32 | -#include "http/request/parser.h" | ||
33 | -#include "http/header.h" | ||
34 | -#include "http/request.h" | ||
35 | -#include "http/message.h" | 32 | +#include "http/parser.h" |
36 | 33 | ||
37 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); | 34 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); |
38 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); | 35 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); |
@@ -45,9 +42,9 @@ httpWorkerProcess(HttpWorker this, int fd) | @@ -45,9 +42,9 @@ httpWorkerProcess(HttpWorker this, int fd) | ||
45 | char buffer[200]; | 42 | char buffer[200]; |
46 | ssize_t size; | 43 | ssize_t size; |
47 | 44 | ||
48 | - if (0 < (size = httpRequestParserParse(this->parser, fd))) { | 45 | + if (0 < (size = httpParserParse(this->parser, fd))) { |
49 | int i; | 46 | int i; |
50 | - HttpMessageQueue reqq = this->parser->request_queue; | 47 | + HttpMessageQueue reqq = this->parser->queue; |
51 | HttpMessageQueue respq = this->writer->response_queue; | 48 | HttpMessageQueue respq = this->writer->response_queue; |
52 | 49 | ||
53 | for (i=0; i<reqq->nmsgs; i++) { | 50 | for (i=0; i<reqq->nmsgs; i++) { |
src/utils/http.c
0 → 100644
1 | +#include <stdlib.h> | ||
2 | +#include <sys/types.h> | ||
3 | +#include <string.h> | ||
4 | + | ||
5 | +#include "http/message.h" | ||
6 | +#include "http/request.h" | ||
7 | +#include "http/response.h" | ||
8 | + | ||
9 | +#include "interface/class.h" | ||
10 | + | ||
11 | +#ifndef TRUE | ||
12 | +#define TRUE 1 | ||
13 | +#endif | ||
14 | + | ||
15 | +#ifndef FALSE | ||
16 | +#define FALSE 0 | ||
17 | +#endif | ||
18 | + | ||
19 | +char | ||
20 | +isHttpVersion(const char * str, size_t len) | ||
21 | +{ | ||
22 | + if (NULL == str) | ||
23 | + return FALSE; | ||
24 | + | ||
25 | + if (8 > len) | ||
26 | + return FALSE; | ||
27 | + | ||
28 | + if (0 != memcmp("HTTP/", str, sizeof("HTTP/")-1)) | ||
29 | + return FALSE; | ||
30 | + | ||
31 | + return TRUE; | ||
32 | +} | ||
33 | + | ||
34 | +HttpMessage | ||
35 | +httpGetMessage( | ||
36 | + const char * part1, size_t len1, | ||
37 | + const char * part2, size_t len2, | ||
38 | + const char * part3, size_t len3) | ||
39 | +{ | ||
40 | + if (isHttpVersion(part1, len1)) { | ||
41 | + return new(HttpResponse, | ||
42 | + part1, len1, | ||
43 | + strtoul(part2, NULL, 10), | ||
44 | + part3, len3); | ||
45 | + } | ||
46 | + | ||
47 | + if (isHttpVersion(part3, len3)) { | ||
48 | + return new(HttpRequest, | ||
49 | + part1, len1, | ||
50 | + part2, len2, | ||
51 | + part3, len3); | ||
52 | + } | ||
53 | + | ||
54 | + return NULL; | ||
55 | +} | ||
56 | + | ||
57 | +// vim: set ts=4 sw=4: |
Please
register
or
login
to post a comment