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 2012-01-18 07:52:07 +0100 Georg Hopp 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 2012-01-17 15:40:07 +0100 Georg Hopp 57 2012-01-17 15:40:07 +0100 Georg Hopp
6 58
1 #ifndef __HTTP_REQUEST_H__ 1 #ifndef __HTTP_REQUEST_H__
2 #define __HTTP_REQUEST_H__ 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 struct { 11 struct {
12 char * name; 12 char * name;
13 char * value; 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 #endif /* __HTTP_REQUEST_H__ */ 20 #endif /* __HTTP_REQUEST_H__ */
1 #ifndef __HTTP_REQUEST_PARSER_H__ 1 #ifndef __HTTP_REQUEST_PARSER_H__
2 #define __HTTP_REQUEST_PARSER_H__ 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 #define HTTP_REQUEST_PARSER_READ_CHUNK 1024 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 #endif /* __HTTP_REQUEST_PARSER_H__ */ 26 #endif /* __HTTP_REQUEST_PARSER_H__ */
31 27
32 // vim: set ts=4 sw=4: 28 // vim: set ts=4 sw=4:
1 #ifndef __HTTP_REQUEST_QUEUE_H__ 1 #ifndef __HTTP_REQUEST_QUEUE_H__
2 #define __HTTP_REQUEST_QUEUE_H__ 2 #define __HTTP_REQUEST_QUEUE_H__
3 3
4 -#include "cclass.h" 4 +#include "class.h"
5 #include "http/request.h" 5 #include "http/request.h"
6 6
7 #define HTTP_REQUEST_QUEUE_MAX 1024 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 size_t nrequests; 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,18 +26,20 @@ typedef void (*server_read_hook)(const char *, size_t);
26 CLASS(Server) { 26 CLASS(Server) {
27 Logger logger; 27 Logger logger;
28 Sock sock; 28 Sock sock;
  29 + void * reader;
  30 +
29 nfds_t nfds; 31 nfds_t nfds;
30 struct pollfd fds[POLL_FD_NSIZE]; 32 struct pollfd fds[POLL_FD_NSIZE];
31 33
32 struct { 34 struct {
33 Sock sock; 35 Sock sock;
  36 + void * reader;
  37 +
34 char * wbuf; 38 char * wbuf;
35 char * rbuf; 39 char * rbuf;
36 unsigned int rpos; 40 unsigned int rpos;
37 unsigned int wpos; 41 unsigned int wpos;
38 } conns[POLL_FD_NSIZE]; 42 } conns[POLL_FD_NSIZE];
39 -  
40 - server_read_hook read_hook;  
41 }; 43 };
42 44
43 void serverRun(Server this); 45 void serverRun(Server this);
@@ -5,10 +5,13 @@ CLASS = class.c interface.c interface/class.c @@ -5,10 +5,13 @@ CLASS = class.c interface.c interface/class.c
5 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c 5 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
6 SERVER = server.c server/run.c server/close_conn.c 6 SERVER = server.c server/run.c server/close_conn.c
7 LOGGER = logger.c logger/stderr.c logger/syslog.c interface/logger.c 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 AM_CFLAGS = -Wall -I ../include/ 10 AM_CFLAGS = -Wall -I ../include/
10 11
11 bin_PROGRAMS = testserver 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 testserver_CFLAGS = -Wall -I ../include/ 17 testserver_CFLAGS = -Wall -I ../include/
1 #include <stdlib.h> 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 #include "http/request_parser.h" 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 this->buffer = malloc(HTTP_REQUEST_PARSER_READ_CHUNK); 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 free(this->buffer); 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 // vim: set ts=4 sw=4: 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,6 +17,7 @@ ctor(void * _this, va_list * params)
17 unsigned int backlog; 17 unsigned int backlog;
18 18
19 this->logger = va_arg(* params, Logger); 19 this->logger = va_arg(* params, Logger);
  20 + this->reader = va_arg(* params, void*);
20 port = va_arg(* params, int); 21 port = va_arg(* params, int);
21 backlog = va_arg(* params, unsigned int); 22 backlog = va_arg(* params, unsigned int);
22 23
@@ -40,6 +41,7 @@ dtor(void * _this) @@ -40,6 +41,7 @@ dtor(void * _this)
40 * @TODO do some finalization...buffer handling...etc. 41 * @TODO do some finalization...buffer handling...etc.
41 */ 42 */
42 delete(&(this->conns[i]).sock); 43 delete(&(this->conns[i]).sock);
  44 + delete(&(this->conns[i]).reader);
43 } 45 }
44 46
45 delete(&this->sock); 47 delete(&this->sock);
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 #include "logger.h" 9 #include "logger.h"
10 #include "signalHandling.h" 10 #include "signalHandling.h"
11 #include "interface/class.h" 11 #include "interface/class.h"
  12 +#include "interface/stream_reader.h"
12 13
13 #undef MAX 14 #undef MAX
14 #define MAX(x,y) ((x) > (y) ? (x) : (y)) 15 #define MAX(x,y) ((x) > (y) ? (x) : (y))
@@ -52,9 +53,10 @@ serverHandleAccept(Server this) @@ -52,9 +53,10 @@ serverHandleAccept(Server this)
52 acc = socketAccept(this->sock, remoteAddr); 53 acc = socketAccept(this->sock, remoteAddr);
53 54
54 if (-1 != acc->handle) { 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 this->nfds++; 60 this->nfds++;
59 } else { 61 } else {
60 delete(&acc); 62 delete(&acc);
@@ -69,32 +71,34 @@ int @@ -69,32 +71,34 @@ int
69 serverRead(Server this) 71 serverRead(Server this)
70 { 72 {
71 unsigned int i; 73 unsigned int i;
72 - size_t _read;  
73 - char buffer[1024];  
74 74
75 for (i=1; i<this->nfds; i++) { 75 for (i=1; i<this->nfds; i++) {
76 if (0 != ((this->fds)[i].revents & POLLIN)) { 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 case 0: 86 case 0:
79 /* 87 /*
80 * normal close: write remaining data 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 case -1: 93 case -1:
85 /* 94 /*
86 * read failure / close connection 95 * read failure / close connection
87 - * FALLTHROUGH  
88 */ 96 */
89 loggerLog(this->logger, LOGGER_INFO, "connection closed..."); 97 loggerLog(this->logger, LOGGER_INFO, "connection closed...");
90 serverCloseConn(this, i); 98 serverCloseConn(this, i);
91 break; 99 break;
92 100
93 default: 101 default:
94 - (this->fds)[i].revents |= POLLIN;  
95 - if (NULL != this->read_hook) {  
96 - this->read_hook(buffer, _read);  
97 - }  
98 break; 102 break;
99 } 103 }
100 } 104 }
@@ -4,33 +4,25 @@ @@ -4,33 +4,25 @@
4 4
5 #include "server.h" 5 #include "server.h"
6 #include "logger.h" 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 int 13 int
22 main() 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 init_signals(); 20 init_signals();
30 serverRun(server); 21 serverRun(server);
31 22
32 delete(&server); 23 delete(&server);
33 delete(&logger); 24 delete(&logger);
  25 + delete(&parser);
34 26
35 return 0; 27 return 0;
36 } 28 }
Please register or login to post a comment