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 | 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 | 27 | #include "class.h" |
28 | -#include "http/request.h" | |
28 | +#include "http/message.h" | |
29 | 29 | #include "http/message/queue.h" |
30 | 30 | #include "cbuf.h" |
31 | 31 | |
... | ... | @@ -38,36 +38,33 @@ |
38 | 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 | 51 | Cbuf buffer; |
52 | 52 | void * ourLock; |
53 | 53 | |
54 | 54 | char * incomplete; |
55 | 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 | 70 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | #include <sys/types.h> |
28 | 28 | |
29 | 29 | #include "class.h" |
30 | -#include "http/request/parser.h" | |
30 | +#include "http/parser.h" | |
31 | 31 | #include "http/response/writer.h" |
32 | 32 | #include "cbuf.h" |
33 | 33 | |
... | ... | @@ -49,13 +49,10 @@ CLASS(HttpWorker) { |
49 | 49 | Cbuf pbuf; |
50 | 50 | Cbuf wbuf; |
51 | 51 | |
52 | - HttpRequestParser parser; | |
52 | + HttpParser parser; | |
53 | 53 | HttpResponseWriter writer; |
54 | 54 | }; |
55 | 55 | |
56 | -ssize_t httpWorkerProcess(HttpWorker, int); | |
57 | -ssize_t httpWorkerWrite(HttpWorker, int); | |
58 | - | |
59 | 56 | #endif // __HTTP_WORKER_H__ |
60 | 57 | |
61 | 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 | 14 | cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \ |
15 | 15 | cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c \ |
16 | 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 | 26 | RESP = http/response.c \ |
22 | 27 | http/response/304.c \ |
23 | 28 | http/response/404.c \ |
24 | 29 | http/response/asset.c \ |
25 | 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 | 41 | WRITER = http/response/writer.c http/response/writer/write.c |
29 | 42 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
30 | 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 | 51 | AM_CFLAGS = -Wall -I ../include/ |
... | ... | @@ -41,6 +55,6 @@ bin_PROGRAMS = testserver |
41 | 55 | testserver_SOURCES = testserver.c \ |
42 | 56 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ |
43 | 57 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ |
44 | - $(UTILS) | |
58 | + $(UTILS) $(MSGQ) | |
45 | 59 | testserver_CFLAGS = -Wall -I ../include/ |
46 | 60 | testserver_LDFLAGS = -lrt | ... | ... |
... | ... | @@ -28,6 +28,13 @@ |
28 | 28 | #include "http/request.h" |
29 | 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 | 39 | char |
33 | 40 | httpMessageHasKeepAlive(HttpMessage message) |
... | ... | @@ -35,7 +42,6 @@ httpMessageHasKeepAlive(HttpMessage message) |
35 | 42 | HttpHeader header; |
36 | 43 | size_t size; |
37 | 44 | char * value; |
38 | - char * keep_alive = "keep-alive"; | |
39 | 45 | |
40 | 46 | header = httpHeaderGet( |
41 | 47 | &(message->header), |
... | ... | @@ -46,21 +52,10 @@ httpMessageHasKeepAlive(HttpMessage message) |
46 | 52 | return 0; |
47 | 53 | } |
48 | 54 | |
49 | - if ((sizeof("keep-alive")-1) != (header->nvalue)[0]) { | |
50 | - return 0; | |
51 | - } | |
52 | - | |
53 | 55 | size = (header->nvalue)[0]; |
54 | 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 | 61 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #include <string.h> |
24 | 24 | |
25 | 25 | #include "http/message.h" |
26 | +#include "utils/http.h" | |
26 | 27 | |
27 | 28 | int |
28 | 29 | httpMessageHasValidVersion(HttpMessage this) |
... | ... | @@ -30,18 +31,12 @@ httpMessageHasValidVersion(HttpMessage this) |
30 | 31 | int major; |
31 | 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 | 35 | return 0; |
38 | 36 | |
39 | 37 | if (0 > httpMessageGetVersion(this, &major, &minor)) |
40 | 38 | return 0; |
41 | 39 | |
42 | - if (0 != memcmp("HTTP/", this->version, sizeof("HTTP/")-1)) | |
43 | - return 0; | |
44 | - | |
45 | 40 | if (1 != major) |
46 | 41 | return 0; |
47 | 42 | ... | ... |
... | ... | @@ -28,9 +28,10 @@ |
28 | 28 | #include "interface/class.h" |
29 | 29 | #include "interface/stream_reader.h" |
30 | 30 | |
31 | -#include "http/request/parser.h" | |
31 | +#include "http/parser.h" | |
32 | 32 | #include "http/message/queue.h" |
33 | 33 | #include "http/request.h" |
34 | +#include "http/response.h" | |
34 | 35 | #include "cbuf.h" |
35 | 36 | |
36 | 37 | #include "utils/memory.h" |
... | ... | @@ -38,33 +39,38 @@ |
38 | 39 | |
39 | 40 | static |
40 | 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 | 54 | return 0; |
49 | 55 | } |
50 | 56 | |
51 | 57 | static |
52 | 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 | 65 | if (TRUE == this->ourLock) |
60 | 66 | cbufRelease(this->buffer); |
61 | 67 | |
62 | 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 | 76 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -20,31 +20,31 @@ |
20 | 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 | 24 | #include <sys/types.h> |
25 | 25 | |
26 | -#include "class.h" | |
27 | -#include "interface/class.h" | |
28 | 26 | #include "http/header.h" |
29 | 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 | 50 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -21,14 +21,14 @@ |
21 | 21 | */ |
22 | 22 | |
23 | 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 | 29 | #include "http/header.h" |
30 | +#include "http/parser.h" | |
26 | 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 | 33 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
34 | 34 | |
... | ... | @@ -37,41 +37,38 @@ |
37 | 37 | * @TODO: not final...input buffer handling not final |
38 | 38 | */ |
39 | 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 | 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 | 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 | 22 | |
23 | 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 | 26 | #include "interface/class.h" |
27 | +#include "interface/http_intro.h" | |
29 | 28 | #include "cbuf.h" |
30 | 29 | |
31 | 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 | 39 | if (cbufIsLocked(this->buffer)) { |
40 | 40 | if (FALSE == this->ourLock) |
... | ... | @@ -57,11 +57,10 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
57 | 57 | |
58 | 58 | while (cont) { |
59 | 59 | switch(this->state) { |
60 | - case HTTP_REQUEST_GARBAGE: | |
60 | + case HTTP_MESSAGE_GARBAGE: | |
61 | 61 | cbufSkipNonAlpha(this->buffer); |
62 | 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 | 65 | else { |
67 | 66 | cbufRelease(this->buffer); |
... | ... | @@ -71,7 +70,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
71 | 70 | |
72 | 71 | break; |
73 | 72 | |
74 | - case HTTP_REQUEST_START: | |
73 | + case HTTP_MESSAGE_START: | |
75 | 74 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { |
76 | 75 | if (! cbufIsEmpty(this->buffer)) { |
77 | 76 | this->isize = this->buffer->bused; |
... | ... | @@ -86,22 +85,17 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
86 | 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 | 90 | cbufRelease(this->buffer); |
97 | 91 | this->ourLock = FALSE; |
98 | 92 | return -1; |
99 | 93 | } |
100 | 94 | |
101 | - this->state = HTTP_REQUEST_REQUEST_LINE_DONE; | |
95 | + this->state = HTTP_MESSAGE_INTRO_DONE; | |
102 | 96 | break; |
103 | 97 | |
104 | - case HTTP_REQUEST_REQUEST_LINE_DONE: | |
98 | + case HTTP_MESSAGE_INTRO_DONE: | |
105 | 99 | if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { |
106 | 100 | if (! cbufIsEmpty(this->buffer)) { |
107 | 101 | this->isize = this->buffer->bused; |
... | ... | @@ -116,46 +110,45 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
116 | 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 | 115 | break; |
128 | 116 | } |
129 | 117 | |
130 | - httpRequestParserGetHeader(this->cur_request, line, line_end); | |
118 | + httpParserHeader(this->current, line, line_end); | |
131 | 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 | 130 | if (cbufIsEmpty(this->buffer)) { |
139 | 131 | cbufRelease(this->buffer); |
140 | 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 | 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 | 149 | * prepare for next request |
157 | 150 | */ |
158 | - this->state = HTTP_REQUEST_GARBAGE; | |
151 | + this->state = HTTP_MESSAGE_GARBAGE; | |
159 | 152 | |
160 | 153 | break; |
161 | 154 | |
... | ... | @@ -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 | 163 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -37,10 +37,25 @@ static |
37 | 37 | int |
38 | 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 | 59 | return 0; |
45 | 60 | } |
46 | 61 | ... | ... |
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | |
7 | 7 | #include "class.h" |
8 | 8 | #include "http/worker.h" |
9 | -#include "http/request/parser.h" | |
9 | +#include "http/parser.h" | |
10 | 10 | #include "http/response/writer.h" |
11 | 11 | |
12 | 12 | #include "interface/class.h" |
... | ... | @@ -34,7 +34,7 @@ httpWorkerCtor(void * _this, va_list * params) |
34 | 34 | sprintf(cbuf_id, "%s_%s", "writer", id); |
35 | 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 | 38 | this->writer = new(HttpResponseWriter, this->wbuf); |
39 | 39 | |
40 | 40 | return 0; |
... | ... | @@ -67,13 +67,16 @@ _clone(void * _this, void * _base) |
67 | 67 | this->pbuf = NULL; |
68 | 68 | this->wbuf = NULL; |
69 | 69 | |
70 | - this->parser = new(HttpRequestParser, base->pbuf); | |
70 | + this->parser = new(HttpParser, base->pbuf); | |
71 | 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 | 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 | 80 | CREATE_CLASS( |
78 | 81 | HttpWorker, |
79 | 82 | NULL, | ... | ... |
... | ... | @@ -29,10 +29,7 @@ |
29 | 29 | #include "http/message.h" |
30 | 30 | #include "http/request.h" |
31 | 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 | 34 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); |
38 | 35 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); |
... | ... | @@ -45,9 +42,9 @@ httpWorkerProcess(HttpWorker this, int fd) |
45 | 42 | char buffer[200]; |
46 | 43 | ssize_t size; |
47 | 44 | |
48 | - if (0 < (size = httpRequestParserParse(this->parser, fd))) { | |
45 | + if (0 < (size = httpParserParse(this->parser, fd))) { | |
49 | 46 | int i; |
50 | - HttpMessageQueue reqq = this->parser->request_queue; | |
47 | + HttpMessageQueue reqq = this->parser->queue; | |
51 | 48 | HttpMessageQueue respq = this->writer->response_queue; |
52 | 49 | |
53 | 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