Commit 90476e07d827a3bf6d5361a91a9958930fbddf9a

Authored by Georg Hopp
1 parent 382fd0be

add StreamReader interface, modify HttpRequestParser and Server to use it

  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
... ...
  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:
... ...
  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