Commit 90476e07d827a3bf6d5361a91a9958930fbddf9a
1 parent
382fd0be
add StreamReader interface, modify HttpRequestParser and Server to use it
Showing
12 changed files
with
233 additions
and
88 deletions
1 | +2012-02-06 11:20:00 +0100 Georg Hopp | |
2 | + | |
3 | + * add StreamReader interface, modify HttpRequestParser and Server to use it (HEAD, master) | |
4 | + | |
5 | +2012-02-06 11:15:00 +0100 Georg Hopp | |
6 | + | |
7 | + * add missing include to stdarg.h | |
8 | + | |
9 | +2012-02-06 10:45:33 +0100 Georg Hopp | |
10 | + | |
11 | + * implement clone selector | |
12 | + | |
13 | +2012-02-06 10:43:59 +0100 Georg Hopp | |
14 | + | |
15 | + * add ability to call interface methods with return value | |
16 | + | |
17 | +2012-02-06 02:37:55 +0100 Georg Hopp | |
18 | + | |
19 | + * make build system work again | |
20 | + | |
21 | +2012-02-06 02:37:24 +0100 Georg Hopp | |
22 | + | |
23 | + * remove inline stuff for now ... add carefully again later perhaps | |
24 | + | |
25 | +2012-02-06 00:57:26 +0100 Georg Hopp | |
26 | + | |
27 | + * and also mod conigure.ac | |
28 | + | |
29 | +2012-02-06 00:55:44 +0100 Georg Hopp | |
30 | + | |
31 | + * makefile modification for new class stuff | |
32 | + | |
33 | +2012-02-05 22:55:16 +0100 Georg Hopp | |
34 | + | |
35 | + * changed class tool. Now multiple interface per class are supported as well as simple inheritence. | |
36 | + | |
37 | +2012-02-05 22:47:10 +0100 Georg Hopp | |
38 | + | |
39 | + * some latest work | |
40 | + | |
41 | +2012-02-05 22:44:59 +0100 Georg Hopp | |
42 | + | |
43 | + * added some documentation | |
44 | + | |
45 | +2012-02-05 22:42:37 +0100 Georg Hopp | |
46 | + | |
47 | + * changes related to server code | |
48 | + | |
49 | +2012-01-19 16:41:41 +0100 Georg Hopp | |
50 | + | |
51 | + * added some valueable thought about cclass and how this structure might evolve to a real class | |
52 | + | |
1 | 53 | 2012-01-18 07:52:07 +0100 Georg Hopp |
2 | 54 | |
3 | - * add testserver and did some fixes not shown by my incomplete tests (HEAD, master) | |
55 | + * add testserver and did some fixes not shown by my incomplete tests | |
4 | 56 | |
5 | 57 | 2012-01-17 15:40:07 +0100 Georg Hopp |
6 | 58 | ... | ... |
1 | 1 | #ifndef __HTTP_REQUEST_H__ |
2 | 2 | #define __HTTP_REQUEST_H__ |
3 | 3 | |
4 | -#include "cclass.h" | |
4 | +#include "class.h" | |
5 | 5 | |
6 | -CLASS(HTTP_REQUEST) { | |
7 | - char * http_version; | |
8 | - char * uri; | |
9 | - char * method; | |
6 | +CLASS(HttpRequest) { | |
7 | + char * http_version; | |
8 | + char * uri; | |
9 | + char * method; | |
10 | 10 | |
11 | 11 | struct { |
12 | 12 | char * name; |
13 | 13 | char * value; |
14 | - } header[128]; | |
14 | + } header[128]; | |
15 | 15 | |
16 | - char * body; | |
17 | - | |
18 | - unsigned char done; | |
16 | + char * body; | |
17 | + char done; | |
19 | 18 | }; |
20 | 19 | |
21 | 20 | #endif /* __HTTP_REQUEST_H__ */ | ... | ... |
1 | 1 | #ifndef __HTTP_REQUEST_PARSER_H__ |
2 | 2 | #define __HTTP_REQUEST_PARSER_H__ |
3 | 3 | |
4 | -#include "cclass.h" | |
5 | -#include "server.h" | |
6 | -#include "http/request.h" | |
7 | -#include "http/request_queue.h" | |
4 | +#include "class.h" | |
5 | +//#include "http/request.h" | |
6 | +//#include "http/request_queue.h" | |
8 | 7 | |
9 | 8 | #define HTTP_REQUEST_PARSER_READ_CHUNK 1024 |
10 | 9 | |
11 | -#define HTTP_REQUEST_PARSER_START 0 | |
12 | -#define HTTP_REQUEST_PARSER_REQUEST_LINE_DONE 1 | |
13 | -#define HTTP_REQUEST_PARSER_HEADERS_DONE 2 | |
14 | -#define HTTP_REQUEST_PARSER_DONE 3 | |
10 | +typedef enum e_HttpRequestState { | |
11 | + HTTP_REQUEST_START=0, | |
12 | + HTTP_REQUEST_REQEUST_LINE_DONE, | |
13 | + HTTP_REQUEST_HEADERS_DONE, | |
14 | + HTTP_REQUEST_DONE | |
15 | +} HttpRequestState; | |
15 | 16 | |
16 | 17 | |
17 | -CLASS(HTTP_REQUEST_PARSER) { | |
18 | - server_read_hook get_data; | |
18 | +CLASS(HttpRequestParser) { | |
19 | + char * buffer; | |
20 | + size_t buffer_used; | |
19 | 21 | |
20 | - char * buffer; | |
21 | - size_t buffer_used; | |
22 | - | |
23 | - HTTP_REQUEST_QUEUE request_queue; | |
24 | - | |
25 | - unsigned char state; | |
22 | + //HttpRequestQueue request_queue; | |
23 | + HttpRequestState state; | |
26 | 24 | }; |
27 | 25 | |
28 | -void http_request_parser_parse(const char * buffer, size_t size); | |
29 | - | |
30 | 26 | #endif /* __HTTP_REQUEST_PARSER_H__ */ |
31 | 27 | |
32 | 28 | // vim: set ts=4 sw=4: | ... | ... |
1 | 1 | #ifndef __HTTP_REQUEST_QUEUE_H__ |
2 | 2 | #define __HTTP_REQUEST_QUEUE_H__ |
3 | 3 | |
4 | -#include "cclass.h" | |
4 | +#include "class.h" | |
5 | 5 | #include "http/request.h" |
6 | 6 | |
7 | 7 | #define HTTP_REQUEST_QUEUE_MAX 1024 |
8 | 8 | |
9 | 9 | |
10 | -CLASS(HTTP_REQUEST_QUEUE) { | |
11 | - REQUEST requests[HTTP_REQUEST_QUEUE_MAX]; | |
10 | +CLASS(HttpRequestQueue) { | |
11 | + HttpRequest requests[HTTP_REQUEST_QUEUE_MAX]; | |
12 | 12 | size_t nrequests; |
13 | 13 | } |
14 | 14 | ... | ... |
include/interface/stream_reader.h
0 → 100644
1 | +#ifndef __STREAM_READER_H__ | |
2 | +#define __STREAM_READER_H__ | |
3 | + | |
4 | +#include <sys/types.h> | |
5 | + | |
6 | +typedef size_t (* fptr_streamReaderRead)(void *, int fd); | |
7 | + | |
8 | +extern const struct interface i_StreamReader; | |
9 | + | |
10 | +struct i_StreamReader { | |
11 | + const struct interface * const _; | |
12 | + fptr_streamReaderRead read; | |
13 | +}; | |
14 | + | |
15 | +extern size_t streamReaderRead(void *, int fd); | |
16 | + | |
17 | +#endif // __STREAM_READER_H__ | |
18 | + | |
19 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -26,18 +26,20 @@ typedef void (*server_read_hook)(const char *, size_t); |
26 | 26 | CLASS(Server) { |
27 | 27 | Logger logger; |
28 | 28 | Sock sock; |
29 | + void * reader; | |
30 | + | |
29 | 31 | nfds_t nfds; |
30 | 32 | struct pollfd fds[POLL_FD_NSIZE]; |
31 | 33 | |
32 | 34 | struct { |
33 | 35 | Sock sock; |
36 | + void * reader; | |
37 | + | |
34 | 38 | char * wbuf; |
35 | 39 | char * rbuf; |
36 | 40 | unsigned int rpos; |
37 | 41 | unsigned int wpos; |
38 | 42 | } conns[POLL_FD_NSIZE]; |
39 | - | |
40 | - server_read_hook read_hook; | |
41 | 43 | }; |
42 | 44 | |
43 | 45 | void serverRun(Server this); | ... | ... |
... | ... | @@ -5,10 +5,13 @@ CLASS = class.c interface.c interface/class.c |
5 | 5 | SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c |
6 | 6 | SERVER = server.c server/run.c server/close_conn.c |
7 | 7 | LOGGER = logger.c logger/stderr.c logger/syslog.c interface/logger.c |
8 | +HTTP = interface/stream_reader.c http/request_parser.c | |
8 | 9 | |
9 | 10 | AM_CFLAGS = -Wall -I ../include/ |
10 | 11 | |
11 | 12 | bin_PROGRAMS = testserver |
12 | 13 | |
13 | -testserver_SOURCES = testserver.c $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) signalHandling.c daemonize.c | |
14 | +testserver_SOURCES = testserver.c \ | |
15 | + $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(HTTP) \ | |
16 | + signalHandling.c daemonize.c | |
14 | 17 | testserver_CFLAGS = -Wall -I ../include/ | ... | ... |
1 | 1 | #include <stdlib.h> |
2 | +#include <string.h> | |
3 | +#include <stdlib.h> | |
4 | +#include <stdio.h> | |
5 | +#include <unistd.h> | |
6 | +#include <sys/types.h> | |
2 | 7 | |
3 | -#include "cclass.h" | |
4 | -#include "http/request.h" | |
8 | +#include "class.h" | |
5 | 9 | #include "http/request_parser.h" |
6 | - | |
7 | - | |
8 | -INIT_CLASS(HTTP_REQUEST_PARSER); | |
9 | - | |
10 | - | |
11 | -__construct(LOGGER) | |
10 | +#include "interface/class.h" | |
11 | +#include "interface/stream_reader.h" | |
12 | +//#include "http/request.h" | |
13 | +//#include "http/request_queue.h" | |
14 | + | |
15 | +static | |
16 | +void | |
17 | +httpRequestParserParse(char * data, size_t * size); | |
18 | + | |
19 | +static | |
20 | +void | |
21 | +ctor(void * _this, va_list * params) | |
12 | 22 | { |
13 | - this->request_queue = va_arg(*params, HTTP_REQUEST_QUEUE); | |
23 | + HttpRequestParser this = _this; | |
24 | + | |
25 | + //this->request_queue = va_arg(*params, HttpRequestQueue); | |
14 | 26 | |
15 | 27 | this->buffer = malloc(HTTP_REQUEST_PARSER_READ_CHUNK); |
16 | 28 | } |
17 | 29 | |
18 | -__destruct(LOGGER) | |
30 | +static | |
31 | +void | |
32 | +dtor(void * _this) | |
19 | 33 | { |
34 | + HttpRequestParser this = _this; | |
35 | + | |
20 | 36 | free(this->buffer); |
21 | 37 | } |
22 | 38 | |
23 | -__jsonConst(LOGGER) {} | |
24 | -__toJson(LOGGER) {} | |
25 | -__clear(LOGGER) {} | |
26 | - | |
27 | - | |
28 | -static void | |
29 | -get_data(HTTP_REQUEST_PARSER this, const char * data, size_t size) | |
39 | +static | |
40 | +void | |
41 | +_clone(void * _this, void * _base) | |
30 | 42 | { |
31 | - size_t remaining, chunks; | |
43 | + HttpRequestParser this = _this; | |
44 | + HttpRequestParser base = _base; | |
45 | + size_t chunks; | |
46 | + | |
47 | + //this->request_queue = base->request_queue; | |
48 | + this->buffer_used = base->buffer_used; | |
32 | 49 | |
33 | - remaining = this->buffer_used % HTTP_REQUEST_PARSER_READ_CHUNK; | |
34 | - chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK; | |
50 | + chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK; | |
51 | + chunks++; | |
35 | 52 | |
36 | - chunks = (0 == remaining) ? chunks++ : chunks; | |
53 | + this->buffer = malloc(chunks * HTTP_REQUEST_PARSER_READ_CHUNK); | |
54 | + memcpy(this->buffer, base->buffer, this->buffer_used); | |
55 | +} | |
37 | 56 | |
38 | - if (size > remaining) { | |
39 | - this->buffer = | |
40 | - realloc(this->buffer, chunks * HTTP_REQUEST_PARSER_READ_CHUNK); | |
57 | +static | |
58 | +size_t | |
59 | +get_data(void * _this, int fd) | |
60 | +{ | |
61 | + HttpRequestParser this = _this; | |
62 | + size_t remaining, chunks; | |
63 | + char buffer[1024]; | |
64 | + | |
65 | + size_t size = read(fd, buffer, 1024); | |
66 | + | |
67 | + if (0 < size) { | |
68 | + remaining = this->buffer_used % HTTP_REQUEST_PARSER_READ_CHUNK; | |
69 | + chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK; | |
70 | + | |
71 | + /** | |
72 | + * because a division always rounds down | |
73 | + * chunks holds exactly the currently allocated chunks if | |
74 | + * remaining equals 0 but there is no space left. | |
75 | + * Else chunks holds the actually allocated amount of chunks | |
76 | + * minus 1. | |
77 | + * For this reason chunks always has to be increased by 1. | |
78 | + */ | |
79 | + chunks++; | |
80 | + | |
81 | + if (size > remaining) { | |
82 | + this->buffer = | |
83 | + realloc(this->buffer, chunks * HTTP_REQUEST_PARSER_READ_CHUNK); | |
84 | + } | |
85 | + | |
86 | + memcpy(this->buffer + this->buffer_used, buffer, size); | |
87 | + this->buffer_used += size; | |
88 | + | |
89 | + httpRequestParserParse(this->buffer, &this->buffer_used); | |
41 | 90 | } |
42 | 91 | |
43 | - memcpy(this->buffer + this->buffer_used, data, size); | |
44 | - this->buffer_used += size; | |
92 | + return size; | |
45 | 93 | } |
46 | 94 | |
47 | -void http_request_parser_parse(const char * data, size_t size) | |
95 | +INIT_IFACE(Class, ctor, dtor, _clone); | |
96 | +INIT_IFACE(StreamReader, get_data); | |
97 | +CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader)); | |
98 | + | |
99 | +static | |
100 | +void | |
101 | +httpRequestParserParse(char * data, size_t * size) | |
48 | 102 | { |
103 | + data[*size] = 0; | |
104 | + printf("%s", data); | |
105 | + *size = 0; | |
49 | 106 | } |
50 | 107 | |
51 | 108 | // vim: set ts=4 sw=4: | ... | ... |
src/interface/stream_reader.c
0 → 100644
1 | +#include "class.h" | |
2 | +#include "interface/stream_reader.h" | |
3 | + | |
4 | +const struct interface i_StreamReader = { | |
5 | + "streamReader", | |
6 | + 1 | |
7 | +}; | |
8 | + | |
9 | +size_t | |
10 | +streamReaderRead(void * object, int fd) | |
11 | +{ | |
12 | + size_t ret; | |
13 | + | |
14 | + RETCALL(object, StreamReader, read, ret, fd); | |
15 | + | |
16 | + return ret; | |
17 | +} | |
18 | + | |
19 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -17,6 +17,7 @@ ctor(void * _this, va_list * params) |
17 | 17 | unsigned int backlog; |
18 | 18 | |
19 | 19 | this->logger = va_arg(* params, Logger); |
20 | + this->reader = va_arg(* params, void*); | |
20 | 21 | port = va_arg(* params, int); |
21 | 22 | backlog = va_arg(* params, unsigned int); |
22 | 23 | |
... | ... | @@ -40,6 +41,7 @@ dtor(void * _this) |
40 | 41 | * @TODO do some finalization...buffer handling...etc. |
41 | 42 | */ |
42 | 43 | delete(&(this->conns[i]).sock); |
44 | + delete(&(this->conns[i]).reader); | |
43 | 45 | } |
44 | 46 | |
45 | 47 | delete(&this->sock); | ... | ... |
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | #include "logger.h" |
10 | 10 | #include "signalHandling.h" |
11 | 11 | #include "interface/class.h" |
12 | +#include "interface/stream_reader.h" | |
12 | 13 | |
13 | 14 | #undef MAX |
14 | 15 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
... | ... | @@ -52,9 +53,10 @@ serverHandleAccept(Server this) |
52 | 53 | acc = socketAccept(this->sock, remoteAddr); |
53 | 54 | |
54 | 55 | if (-1 != acc->handle) { |
55 | - (this->conns)[this->nfds].sock = acc; // save the socket handle | |
56 | - (this->fds)[this->nfds].fd = acc->handle; | |
57 | - (this->fds)[this->nfds].events = POLLIN; | |
56 | + (this->conns)[this->nfds].sock = acc; // save the socket handle | |
57 | + (this->conns)[this->nfds].reader = clone(this->reader); // clone reader | |
58 | + (this->fds)[this->nfds].fd = acc->handle; | |
59 | + (this->fds)[this->nfds].events = POLLIN; | |
58 | 60 | this->nfds++; |
59 | 61 | } else { |
60 | 62 | delete(&acc); |
... | ... | @@ -69,32 +71,34 @@ int |
69 | 71 | serverRead(Server this) |
70 | 72 | { |
71 | 73 | unsigned int i; |
72 | - size_t _read; | |
73 | - char buffer[1024]; | |
74 | 74 | |
75 | 75 | for (i=1; i<this->nfds; i++) { |
76 | 76 | if (0 != ((this->fds)[i].revents & POLLIN)) { |
77 | - switch (_read = read((this->fds)[i].fd, buffer, 1024)) { | |
77 | + if (NULL == (this->conns)[i].reader) { | |
78 | + loggerLog( | |
79 | + this->logger, | |
80 | + LOGGER_INFO, | |
81 | + "initialization error: NULL reader"); | |
82 | + serverCloseConn(this, i); | |
83 | + } | |
84 | + | |
85 | + switch (streamReaderRead((this->conns)[i].reader, (this->fds)[i].fd)) { | |
78 | 86 | case 0: |
79 | 87 | /* |
80 | 88 | * normal close: write remaining data |
89 | + * @TODO: actually we have no remaining data here.... | |
81 | 90 | */ |
82 | - /* FALLTHROUGH */ | |
91 | + /* DROP-THROUGH */ | |
83 | 92 | |
84 | 93 | case -1: |
85 | 94 | /* |
86 | 95 | * read failure / close connection |
87 | - * FALLTHROUGH | |
88 | 96 | */ |
89 | 97 | loggerLog(this->logger, LOGGER_INFO, "connection closed..."); |
90 | 98 | serverCloseConn(this, i); |
91 | 99 | break; |
92 | 100 | |
93 | 101 | default: |
94 | - (this->fds)[i].revents |= POLLIN; | |
95 | - if (NULL != this->read_hook) { | |
96 | - this->read_hook(buffer, _read); | |
97 | - } | |
98 | 102 | break; |
99 | 103 | } |
100 | 104 | } | ... | ... |
... | ... | @@ -4,33 +4,25 @@ |
4 | 4 | |
5 | 5 | #include "server.h" |
6 | 6 | #include "logger.h" |
7 | -#include "signalHandling.h" | |
8 | -#include "interface/class.h" | |
9 | - | |
10 | -static void | |
11 | -read_hook(const char * _buffer, size_t size) | |
12 | -{ | |
13 | - char buffer[1025]; | |
7 | +#include "http/request_parser.h" | |
14 | 8 | |
15 | - memset(buffer, 0, 1025); | |
16 | - snprintf(buffer, 1025>size? size : 1024, "%s", _buffer); | |
9 | +#include "signalHandling.h" | |
17 | 10 | |
18 | - printf("%s\n", buffer); | |
19 | -} | |
11 | +#include "interface/class.h" | |
20 | 12 | |
21 | 13 | int |
22 | 14 | main() |
23 | 15 | { |
24 | - Logger logger = new(LoggerStderr, LOGGER_INFO); | |
25 | - Server server = new(Server, logger, 11212, SOMAXCONN); | |
26 | - | |
27 | - server->read_hook = read_hook; | |
16 | + Logger logger = new(LoggerStderr, LOGGER_INFO); | |
17 | + HttpRequestParser parser = new(HttpRequestParser); | |
18 | + Server server = new(Server, logger, parser, 11212, SOMAXCONN); | |
28 | 19 | |
29 | 20 | init_signals(); |
30 | 21 | serverRun(server); |
31 | 22 | |
32 | 23 | delete(&server); |
33 | 24 | delete(&logger); |
25 | + delete(&parser); | |
34 | 26 | |
35 | 27 | return 0; |
36 | 28 | } | ... | ... |
Please
register
or
login
to post a comment