Commit ee6040201e81ed11f1ee8cea198e612e56aaec70

Authored by Georg Hopp
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
@@ -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:
  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:
  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++) {
  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