Commit e8a21ace314922f3db29446bc56e10f9b557169f

Authored by Georg Hopp
1 parent 5c1c6a80

lots of changes but primarily change the request parser to use a ringbuffer. The…

… ringbuffer is implemented using the shared memory trick.
  1 +2012-02-18 20:12:27 +0100 Georg Hopp
  2 +
  3 + * lots of changes but primarily change the request parser to use a ringbuffer. The ringbuffer is implemented using the shared memory trick. (HEAD, master)
  4 +
1 5 2012-02-15 12:30:33 +0100 Georg Hopp
2 6
3   - * some more cleanups in the server code. Removing not needed header includes (HEAD, master)
  7 + * some more cleanups in the server code. Removing not needed header includes (origin/master, origin/HEAD)
4 8
5 9 2012-02-15 12:17:39 +0100 Georg Hopp
6 10
7   - * Merge branch 'master' of 192.168.100.2:/var/lib/git/server (origin/master, origin/HEAD)
  11 + * Merge branch 'master' of 192.168.100.2:/var/lib/git/server
8 12
9 13 2012-02-15 12:17:00 +0100 Georg Hopp
10 14
... ...
  1 +POST / HTTP/1.1
  2 +Host: localhost:11213
  3 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20100101 Firefox/8.0
  4 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5 +Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
  6 +Accept-Encoding: gzip, deflate
  7 +Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
  8 +Connection: keep-alive
  9 +Referer: http://localhost:11213/
  10 +Content-Type: multipart/form-data; boundary=---------------------------2713599294882465121951036798
  11 +Content-Length: 2652
  12 +
  13 +-----------------------------2713599294882465121951036798
  14 +Content-Disposition: form-data; name="submitter"
  15 +
  16 +fooo
  17 +-----------------------------2713599294882465121951036798
  18 +Content-Disposition: form-data; name="pics"; filename="bar.c"
  19 +Content-Type: text/x-csrc
  20 +
  21 +#include <stdio.h>
  22 +
  23 +#define _B64(chr, ref) (chr)==_##ref?__##ref
  24 +#define B64(_) \
  25 + ( _B64(_,A):_B64(_,B):_B64(_,C):_B64(_,D):_B64(_,E):_B64(_,F):_B64(_,G): \
  26 + _B64(_,H):_B64(_,I):_B64(_,J):_B64(_,K):_B64(_,L):_B64(_,M):_B64(_,N): \
  27 + _B64(_,O):_B64(_,P):_B64(_,Q):_B64(_,R):_B64(_,S):_B64(_,T):_B64(_,U): \
  28 + _B64(_,V):_B64(_,W):_B64(_,X):_B64(_,Y):_B64(_,Z):_B64(_,a):_B64(_,b): \
  29 + _B64(_,c):_B64(_,d):_B64(_,e):_B64(_,f):_B64(_,g):_B64(_,h):_B64(_,i): \
  30 + _B64(_,j):_B64(_,k):_B64(_,l):_B64(_,m):_B64(_,n):_B64(_,o):_B64(_,p): \
  31 + _B64(_,q):_B64(_,r):_B64(_,s):_B64(_,t):_B64(_,u):_B64(_,v):_B64(_,w): \
  32 + _B64(_,x):_B64(_,y):_B64(_,z):_B64(_,0):_B64(_,1):_B64(_,2):_B64(_,3): \
  33 + _B64(_,4):_B64(_,5):_B64(_,6):_B64(_,7):_B64(_,8):_B64(_,9): \
  34 + _B64(_,PLUS):_B64(_,SLASH):-1 )
  35 +
  36 +
  37 +#define B64_8(_) \
  38 + B64(_),B64(_+1),B64(_+2),B64(_+3),B64(_+4),B64(_+5),B64(_+6),B64(_+7)
  39 +
  40 +#define B64_64(_) \
  41 + B64_8(_),B64_8(_+8), B64_8(_+16),B64_8(_+24), \
  42 + B64_8(_+32),B64_8(_+40),B64_8(_+48),B64_8(_+56)
  43 +
  44 +#define IS_BASE64(ch) ( \
  45 + UCHAR_IN_RANGE((unsigned char)(ch)) \
  46 + && 0 <= b64[(unsigned char)(ch)] )
  47 +
  48 +
  49 +static const char b64str[64] =
  50 +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  51 +
  52 +enum b64vals {
  53 + __A=0,__B,__C,__D,__E,__F,__G,__H,__I,__J,__K,__L,__M,__N,__O,__P,__Q,__R,
  54 + __S,__T,__U,__V,__W,__X,__Y,__Z,__a,__b,__c,__d,__e,__f,__g,__h,__i,__j,
  55 + __k,__l,__m,__n,__o,__p,__q,__r,__s,__t,__u,__v,__w,__x,__y,__z,__0,__1,
  56 + __2,__3,__4,__5,__6,__7,__8,__9,__PLUS,__SLASH
  57 +};
  58 +
  59 +enum b64chars {
  60 + _A='A',_B='B',_C='C',_D='D',_E='E',_F='F',_G='G',_H='H',_I='I',_J='J',_K='K',
  61 + _L='L',_M='M',_N='N',_O='O',_P='P',_Q='Q',_R='R',_S='S',_T='T',_U='U',_V='V',
  62 + _W='W',_X='X',_Y='Y',_Z='Z',_a='a',_b='b',_c='c',_d='d',_e='e',_f='f',_g='g',
  63 + _h='h',_i='i',_j='j',_k='k',_l='l',_m='m',_n='n',_o='o',_p='p',_q='q',_r='r',
  64 + _s='s',_t='t',_u='u',_v='v',_w='w',_x='x',_y='y',_z='z',_0='0',_1='1',_2='2',
  65 + _3='3',_4='4',_5='5',_6='6',_7='7',_8='8',_9='9',_PLUS='+',_SLASH='/'
  66 +};
  67 +
  68 +#define __46B(chr) __##chr
  69 +inline
  70 +char
  71 +__B64(int val)
  72 +{
  73 + return b64str[val];
  74 +}
  75 +
  76 +int main()
  77 +{
  78 + int i=12;
  79 + char a='k';
  80 +
  81 + //printf("i => %c | a => %d\n", __B64(12), __46B('k'));
  82 + printf("i => %c | a => %d\n", __B64(i), __46B(a));
  83 +}
  84 +
  85 +// vim: set ts=4 sw=4:
  86 +
  87 +-----------------------------2713599294882465121951036798--
... ...
  1 +-----------------------------2713599294882465121951036798
  2 +Content-Disposition: form-data; name="submitter"
  3 +
  4 +fooo
  5 +-----------------------------2713599294882465121951036798
  6 +Content-Disposition: form-data; name="pics"; filename="bar.c"
  7 +Content-Type: text/x-csrc
  8 +
  9 +#include <stdio.h>
  10 +
  11 +#define _B64(chr, ref) (chr)==_##ref?__##ref
  12 +#define B64(_) \
  13 + ( _B64(_,A):_B64(_,B):_B64(_,C):_B64(_,D):_B64(_,E):_B64(_,F):_B64(_,G): \
  14 + _B64(_,H):_B64(_,I):_B64(_,J):_B64(_,K):_B64(_,L):_B64(_,M):_B64(_,N): \
  15 + _B64(_,O):_B64(_,P):_B64(_,Q):_B64(_,R):_B64(_,S):_B64(_,T):_B64(_,U): \
  16 + _B64(_,V):_B64(_,W):_B64(_,X):_B64(_,Y):_B64(_,Z):_B64(_,a):_B64(_,b): \
  17 + _B64(_,c):_B64(_,d):_B64(_,e):_B64(_,f):_B64(_,g):_B64(_,h):_B64(_,i): \
  18 + _B64(_,j):_B64(_,k):_B64(_,l):_B64(_,m):_B64(_,n):_B64(_,o):_B64(_,p): \
  19 + _B64(_,q):_B64(_,r):_B64(_,s):_B64(_,t):_B64(_,u):_B64(_,v):_B64(_,w): \
  20 + _B64(_,x):_B64(_,y):_B64(_,z):_B64(_,0):_B64(_,1):_B64(_,2):_B64(_,3): \
  21 + _B64(_,4):_B64(_,5):_B64(_,6):_B64(_,7):_B64(_,8):_B64(_,9): \
  22 + _B64(_,PLUS):_B64(_,SLASH):-1 )
  23 +
  24 +
  25 +#define B64_8(_) \
  26 + B64(_),B64(_+1),B64(_+2),B64(_+3),B64(_+4),B64(_+5),B64(_+6),B64(_+7)
  27 +
  28 +#define B64_64(_) \
  29 + B64_8(_),B64_8(_+8), B64_8(_+16),B64_8(_+24), \
  30 + B64_8(_+32),B64_8(_+40),B64_8(_+48),B64_8(_+56)
  31 +
  32 +#define IS_BASE64(ch) ( \
  33 + UCHAR_IN_RANGE((unsigned char)(ch)) \
  34 + && 0 <= b64[(unsigned char)(ch)] )
  35 +
  36 +
  37 +static const char b64str[64] =
  38 +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  39 +
  40 +enum b64vals {
  41 + __A=0,__B,__C,__D,__E,__F,__G,__H,__I,__J,__K,__L,__M,__N,__O,__P,__Q,__R,
  42 + __S,__T,__U,__V,__W,__X,__Y,__Z,__a,__b,__c,__d,__e,__f,__g,__h,__i,__j,
  43 + __k,__l,__m,__n,__o,__p,__q,__r,__s,__t,__u,__v,__w,__x,__y,__z,__0,__1,
  44 + __2,__3,__4,__5,__6,__7,__8,__9,__PLUS,__SLASH
  45 +};
  46 +
  47 +enum b64chars {
  48 + _A='A',_B='B',_C='C',_D='D',_E='E',_F='F',_G='G',_H='H',_I='I',_J='J',_K='K',
  49 + _L='L',_M='M',_N='N',_O='O',_P='P',_Q='Q',_R='R',_S='S',_T='T',_U='U',_V='V',
  50 + _W='W',_X='X',_Y='Y',_Z='Z',_a='a',_b='b',_c='c',_d='d',_e='e',_f='f',_g='g',
  51 + _h='h',_i='i',_j='j',_k='k',_l='l',_m='m',_n='n',_o='o',_p='p',_q='q',_r='r',
  52 + _s='s',_t='t',_u='u',_v='v',_w='w',_x='x',_y='y',_z='z',_0='0',_1='1',_2='2',
  53 + _3='3',_4='4',_5='5',_6='6',_7='7',_8='8',_9='9',_PLUS='+',_SLASH='/'
  54 +};
  55 +
  56 +#define __46B(chr) __##chr
  57 +inline
  58 +char
  59 +__B64(int val)
  60 +{
  61 + return b64str[val];
  62 +}
  63 +
  64 +int main()
  65 +{
  66 + int i=12;
  67 + char a='k';
  68 +
  69 + //printf("i => %c | a => %d\n", __B64(12), __46B('k'));
  70 + printf("i => %c | a => %d\n", __B64(i), __46B(a));
  71 +}
  72 +
  73 +// vim: set ts=4 sw=4:
  74 +
  75 +-----------------------------2713599294882465121951036798--
... ...
... ... @@ -4,11 +4,21 @@
4 4 #include "class.h"
5 5 #include "http/request.h"
6 6 #include "http/message/queue.h"
  7 +#include "ringbuffer.h"
7 8
8   -#define HTTP_REQUEST_PARSER_READ_CHUNK 1024
  9 +#define HTTP_REQUEST_PARSER_MAX_BUF 131072
9 10
10   -#define REMAINS(pars) \
11   - ((pars)->buffer_used - ((pars)->cur_data - (pars)->buffer))
  11 +/**
  12 + * limits to stop invalid requests from killing
  13 + * the server.
  14 + * If any of these limits is reached the server
  15 + * will send an error message and kill the connection
  16 + * immediate.
  17 + *
  18 + * The given limits include any trailing \r\n
  19 + */
  20 +#define HTTP_REQUEST_LINE_MAX 8192
  21 +#define HTTP_REQUEST_HEADER_LINE_MAX 2048
12 22
13 23
14 24 typedef enum e_HttpRequestState {
... ... @@ -21,11 +31,7 @@ typedef enum e_HttpRequestState {
21 31
22 32
23 33 CLASS(HttpRequestParser) {
24   - char * buffer;
25   - char * cur_data;
26   -
27   - size_t buffer_used;
28   - size_t buffer_size;
  34 + Ringbuffer buffer;
29 35
30 36 HttpMessageQueue request_queue;
31 37 HttpRequest cur_request;
... ... @@ -34,11 +40,11 @@ CLASS(HttpRequestParser) {
34 40 };
35 41
36 42 ssize_t httpRequestParserRead(HttpRequestParser, int);
37   -ssize_t httpRequestParserParse(HttpRequestParser);
38   -void httpRequestParserGetBody(HttpRequestParser);
  43 +ssize_t httpRequestParserParse(HttpRequestParser, int);
39 44
40   -void httpRequestParserGetRequestLine(HttpRequest, char *);
41   -void httpRequestParserGetHeader(HttpRequest, char *);
  45 +ssize_t httpRequestParserGetRequestLine(HttpRequestParser, char *);
  46 +ssize_t httpRequestParserGetHeader(HttpRequestParser, char *);
  47 +void httpRequestParserGetBody(HttpRequestParser);
42 48
43 49 #endif /* __HTTP_REQUEST_PARSER_H__ */
44 50
... ...
... ... @@ -8,6 +8,9 @@
8 8 #include "http/response/writer.h"
9 9
10 10 CLASS(HttpWorker) {
  11 + char * remoteAddr;
  12 + int handle;
  13 +
11 14 HttpRequestParser parser;
12 15 HttpResponseWriter writer;
13 16 };
... ...
  1 +/**
  2 + * my implementation of a ringbuffer.
  3 + * It maps a shared memory object twice directly following
  4 + * thus make it possible to read and write from any
  5 + * position within the buffer without the nasty wrap
  6 + * calculations.
  7 + * This is achived because the same memory region is mapped
  8 + * at the two addresses.
  9 + */
  10 +#ifndef __RINGBUFFER_H__
  11 +#define __RINGBUFFER_H__
  12 +
  13 +#include <sys/types.h>
  14 +
  15 +#include "class.h"
  16 +
  17 +#define ERBOVRFL 100
  18 +
  19 +
  20 +CLASS(Ringbuffer) {
  21 + char * shm_name; // shared memory identifier
  22 +
  23 + char * buffer;
  24 + char * mirror;
  25 +
  26 + size_t bsize;
  27 + size_t bused;
  28 + size_t bstart;
  29 + size_t bend;
  30 +};
  31 +
  32 +ssize_t rbRead(Ringbuffer, int fd);
  33 +ssize_t rbWrite(Ringbuffer, int fd);
  34 +
  35 +#endif // __RINGBUFFER_H__
  36 +
  37 +// vim: set ts=4 sw=4:
... ...
... ... @@ -15,7 +15,7 @@ CLASS(Sock) {
15 15
16 16 void socketConnect(Sock this, const char * addr);
17 17 void socketListen(Sock this, int backlog);
18   -Sock socketAccept(Sock this, char remoteAddr[16]);
  18 +Sock socketAccept(Sock this, char (*remoteAddr)[]);
19 19
20 20 #endif // __SOCKET_H__
21 21
... ...
... ... @@ -5,6 +5,7 @@ IFACE = interface/class.c interface/stream_reader.c interface/logger.c \
5 5 interface/stream_writer.c interface/http_intro.c \
6 6 interface/subject.c interface/observer.c
7 7 CLASS = class.c interface.c
  8 +RB = ringbuffer.c ringbuffer/rb_read.c
8 9 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
9 10 SERVER = server.c server/run.c server/close_conn.c
10 11 LOGGER = logger.c logger/stderr.c logger/syslog.c
... ... @@ -21,7 +22,7 @@ HEADER = http/header.c http/header/get.c http/header/add.c \
21 22 http/header/size_get.c http/header/to_string.c
22 23 PARSER = http/request/parser.c http/request/parser/get_header.c \
23 24 http/request/parser/parse.c http/request/parser/get_request_line.c \
24   - http/request/parser/read.c http/request/parser/get_body.c
  25 + http/request/parser/get_body.c
25 26
26 27
27 28 AM_CFLAGS = -Wall -I ../include/
... ... @@ -30,6 +31,7 @@ bin_PROGRAMS = testserver
30 31
31 32 testserver_SOURCES = testserver.c \
32 33 $(IFACE) $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \
33   - $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) \
  34 + $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(RB) \
34 35 signalHandling.c daemonize.c
35 36 testserver_CFLAGS = -Wall -I ../include/
  37 +testserver_LDFLAGS = -lrt
... ...
... ... @@ -10,18 +10,18 @@
10 10 #include "http/request/parser.h"
11 11 #include "http/message/queue.h"
12 12 #include "http/request.h"
  13 +#include "ringbuffer.h"
13 14
14 15
15 16 static
16 17 void
17 18 ctor(void * _this, va_list * params)
18 19 {
19   - HttpRequestParser this = _this;
  20 + HttpRequestParser this = _this;
  21 + char * shm_name = va_arg(*params, char*);
20 22
  23 + this->buffer = new(Ringbuffer, shm_name, HTTP_REQUEST_LINE_MAX);
21 24 this->request_queue = new(HttpMessageQueue);
22   -
23   - this->buffer = malloc(HTTP_REQUEST_PARSER_READ_CHUNK);
24   - this->buffer[0] = 0;
25 25 }
26 26
27 27 static
... ... @@ -30,36 +30,16 @@ dtor(void * _this)
30 30 {
31 31 HttpRequestParser this = _this;
32 32
33   - free(this->buffer);
34 33 delete(&(this->request_queue));
  34 + delete(&(this->buffer));
35 35
36 36 if (NULL != this->cur_request)
37 37 delete(&(this->cur_request));
38 38 }
39 39
40   -static
41   -void
42   -_clone(void * _this, void * _base)
43   -{
44   - HttpRequestParser this = _this;
45   - HttpRequestParser base = _base;
46   - size_t chunks;
47   -
48   - /**
49   - * every parser has its own queue...
50   - */
51   - this->request_queue = new(HttpMessageQueue);
52   - this->buffer_used = base->buffer_used;
53   -
54   - chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK;
55   - chunks++;
56   -
57   - this->buffer = malloc(chunks * HTTP_REQUEST_PARSER_READ_CHUNK);
58   - memcpy(this->buffer, base->buffer, this->buffer_used);
59   -}
60 40
61   -INIT_IFACE(Class, ctor, dtor, _clone);
62   -INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserRead);
  41 +INIT_IFACE(Class, ctor, dtor, NULL);
  42 +INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserParse);
63 43 CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader));
64 44
65 45 // vim: set ts=4 sw=4:
... ...
... ... @@ -4,33 +4,50 @@
4 4 #include "http/message.h"
5 5 #include "http/request/parser.h"
6 6
  7 +#define MAX(x,y) ((x) > (y) ? (x) : (y))
  8 +
  9 +
  10 +/**
  11 + * @TODO: not final...input buffer handling not final
  12 + */
7 13 void
8 14 httpRequestParserGetBody(HttpRequestParser this)
9 15 {
10 16 HttpMessage message = (HttpMessage)(this->cur_request);
11   - char * nbody;
  17 + char * str_nbody;
  18 + int nbody;
  19 + int len;
  20 +
  21 + str_nbody = httpHeaderGet(
  22 + &(message->header),
  23 + "Content-Length");
  24 +
  25 + if (NULL == str_nbody) {
  26 + this->state = HTTP_REQUEST_DONE;
  27 + return -1;
  28 + }
  29 +
  30 + nbody = atoi(str_nbody);
12 31
13 32 if (0 == message->nbody) {
14   - nbody = httpHeaderGet(
15   - &(message->header),
16   - "Content-Length");
17   -
18   - if (NULL == nbody) {
19   - this->state = HTTP_REQUEST_DONE;
20   - return;
21   - }
22   - else {
23   - message->type = HTTP_MESSAGE_BUFFERED;
24   - message->nbody = atoi(nbody);
25   - }
  33 + message->type = HTTP_MESSAGE_BUFFERED;
  34 + if (0 < nbody)
  35 + message->body = malloc(nbody);
  36 + }
  37 +
  38 + len = MAX(nbody - message->nbody, this->buffer->bused);
  39 + memcpy(message->body + message->nbody,
  40 + this->buffer->buffer + this->buffer->bstart,
  41 + len);
  42 +
  43 + message->nbody += len;
  44 + this->buffer->bstart += len;
  45 + if (this->buffer->bstart >= this->buffer->bsize) {
  46 + this->buffer->bstart -= this->buffer->bsize;
26 47 }
  48 + this->buffer->bused -= len;
27 49
28   - if (REMAINS(this) >= message->nbody) {
29   - message->body = calloc(1, message->nbody + 1);
30   - memcpy(message->body,
31   - this->cur_data,
32   - message->nbody);
33   - this->cur_data += message->nbody;
  50 + if (message->nbody == nbody) {
34 51 this->state = HTTP_REQUEST_DONE;
35 52 }
36 53 }
... ...
  1 +#include <stdlib.h>
  2 +#include <string.h>
1 3 #include <search.h>
2 4 #include <ctype.h>
3 5 #include <stdio.h>
... ... @@ -6,17 +8,32 @@
6 8 #include "interface/class.h"
7 9 #include "http/header.h"
8 10 #include "http/message.h"
  11 +#include "http/request/parser.h"
  12 +#include "ringbuffer.h"
9 13
10   -void
11   -httpRequestParserGetHeader(HttpMessage request, char * line)
  14 +ssize_t
  15 +httpRequestParserGetHeader(HttpRequestParser this, char * cr)
12 16 {
13   - char * name = line;
14   - char * value = strchr(line, ':');
  17 + HttpMessage message = (HttpMessage)this->cur_request;
  18 + char * value;
  19 + char * name = this->buffer->buffer + this->buffer->bstart;
  20 + size_t len = cr - name;
15 21
  22 + value = memchr(
  23 + this->buffer->buffer + this->buffer->bstart,
  24 + ':', len);
  25 +
  26 + if (NULL == value) {
  27 + return -1;
  28 + }
  29 +
  30 + *cr = 0;
16 31 *(value++) = 0;
17   - for (; *value == ' ' && *value != 0; value++);
  32 + while(' ' == *value) value++;
  33 +
  34 + httpHeaderAdd(&(message->header), new(HttpHeader, name, value));
18 35
19   - httpHeaderAdd(&(request->header), new(HttpHeader, name, value));
  36 + return 1; //* @TODO: return something useful here
20 37 }
21 38
22 39 // vim: set ts=4 sw=4:
... ...
1 1 #include <stdlib.h>
2 2 #include <string.h>
3 3
  4 +#include "http/message.h"
4 5 #include "http/request.h"
  6 +#include "http/request/parser.h"
  7 +#include "ringbuffer.h"
5 8
  9 +#define MAX(x,y) ((x) > (y) ? (x) : (y))
  10 +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  11 +#define MIN_SIZE(x,y) (MAX(strlen((x)), (y)))
6 12
7   -void
8   -httpRequestParserGetRequestLine(HttpRequest request, char * line)
  13 +enum e_method {
  14 + OPTIONS=0,
  15 + GET,
  16 + HEAD,
  17 + POST,
  18 + PUT,
  19 + DELETE,
  20 + TRACE,
  21 + CONNECT
  22 +};
  23 +
  24 +#define N_METHODS 8
  25 +
  26 +static
  27 +const
  28 +char * method[N_METHODS] = {
  29 + "OPTIONS",
  30 + "GET",
  31 + "HEAD",
  32 + "POST",
  33 + "PUT",
  34 + "DELETE",
  35 + "TRACE",
  36 + "CONNECT"
  37 +};
  38 +
  39 +ssize_t
  40 +httpRequestParserGetRequestLine(HttpRequestParser this, char * cr)
9 41 {
  42 + HttpRequest request = this->cur_request;
10 43 HttpMessage message = (HttpMessage)request;
11   - char * method, * uri, * version;
  44 + char * space1, * space2;
  45 + size_t len = cr - this->buffer->buffer - this->buffer->bstart;
  46 + int i;
  47 +
  48 + space1 = memchr(
  49 + this->buffer->buffer + this->buffer->bstart,
  50 + ' ', len);
  51 +
  52 + if (NULL == space1) {
  53 + return -1;
  54 + }
  55 +
  56 + len = cr - space1;
  57 + space2 = memchr(space1 + 1, ' ', len);
  58 +
  59 + if (NULL == space2) {
  60 + return -1;
  61 + }
  62 +
  63 + len = space1 - this->buffer->buffer - this->buffer->bstart;
  64 + request->method = calloc(1, len + 1);
  65 + memcpy(request->method,
  66 + this->buffer->buffer + this->buffer->bstart,
  67 + len);
  68 +
  69 + for (i= 0; i< N_METHODS; i++) {
  70 + if (0 == memcmp(method[i], request->method, MIN_SIZE(method[i], len))) {
  71 + break;
  72 + }
  73 + }
  74 +
  75 + if (i == N_METHODS) {
  76 + return -1;
  77 + }
12 78
13   - method = line;
  79 + len = space2 - space1 - 1;
  80 + request->uri = calloc(1, len + 1);
  81 + memcpy(request->uri, space1 + 1, len);
14 82
15   - uri = strchr(line, ' ');
16   - *uri++ = 0;
17   - for (; *uri == ' ' && *uri != 0; uri++);
  83 + len = cr - space2 - 1;
  84 + message->version = calloc(1, len + 1);
  85 + memcpy(message->version, space2 + 1, len);
18 86
19   - version = strchr(uri, ' ');
20   - *version++ = 0;
21   - for (; *version == ' ' && *version != 0; version++);
  87 + if (len+1 != sizeof("HTTP/1.1") ||
  88 + 0 != memcmp("HTTP/1.", message->version, len-1)) {
  89 + return -1;
  90 + }
22 91
23   - request->method = malloc(strlen(method) + 1);
24   - strcpy(request->method, method);
25   - request->uri = malloc(strlen(uri) + 1);
26   - strcpy(request->uri, uri);
27   - message->version = malloc(strlen(version) + 1);
28   - strcpy(message->version, method);
  92 + return 1; //* @TODO: return something useful here
29 93 }
30 94
31 95 // vim: set ts=4 sw=4:
... ...
... ... @@ -3,112 +3,147 @@
3 3 #include <unistd.h>
4 4 #include <ctype.h>
5 5
  6 +#include "http/request.h"
  7 +#include "http/message.h"
6 8 #include "http/request/parser.h"
7 9 #include "interface/class.h"
8 10
  11 +#ifndef TRUE
  12 +#define TRUE 1
  13 +#endif
  14 +
  15 +#ifndef FALSE
  16 +#define FALSE 0
  17 +#endif
9 18
10 19 static
11 20 inline
12 21 char *
13   -httpRequestParserGetLine(char ** data)
  22 +getLine(HttpRequestParser this)
14 23 {
15   - char * line_end = strstr(*data, "\r\n");
16   - char * ret = *data;
  24 + char * cr = memchr(
  25 + this->buffer->buffer + this->buffer->bstart,
  26 + '\r',
  27 + this->buffer->bused);
17 28
18   - if (NULL == line_end) {
19   - return NULL;
20   - }
  29 + char * nl = (NULL == cr)? NULL : cr + 1;
21 30
22   - *line_end = 0;
23   - *data = line_end + 2;
  31 + if (NULL != cr && NULL != nl && '\n' == *nl) {
  32 + *cr = 0;
  33 + return cr;
  34 + }
24 35
25   - return ret;
  36 + return NULL;
26 37 }
27 38
28 39 static
29 40 inline
30   -void
31   -httpRequestSkip(char ** data)
  41 +char
  42 +httpRequestSkip(HttpRequestParser this)
32 43 {
33   - for (; 0 != **data && ! isalpha(**data); (*data)++);
  44 + while (this->buffer->bused > 0 &&
  45 + ! isalpha(this->buffer->buffer[this->buffer->bstart])) {
  46 + this->buffer->bstart = (this->buffer->bstart >= this->buffer->bsize)?
  47 + 0 : this->buffer->bstart + 1;
  48 + this->buffer->bused--;
  49 + }
  50 +
  51 + return (isalpha(this->buffer->buffer[this->buffer->bstart]))? TRUE : FALSE;
34 52 }
35 53
36 54 ssize_t
37   -httpRequestParserParse(HttpRequestParser this)
  55 +httpRequestParserParse(HttpRequestParser this, int fd)
38 56 {
39   - char * line;
40 57 int cont = 1;
41   - ssize_t ret = this->request_queue->nmsgs;
  58 + ssize_t ret;
  59 +
  60 + if (0 > (ret = rbRead(this->buffer, fd))) {
  61 + cont = 0;
  62 + }
42 63
43 64 while (cont) {
44 65 switch(this->state) {
45   - case HTTP_REQUEST_GARBAGE:
46   - this->cur_data = this->buffer; // initialize static pointer
47   - httpRequestSkip(&(this->cur_data));
48   - this->cur_request = new(HttpRequest);
  66 + char * line_end;
  67 + size_t len;
49 68
50   - this->state = HTTP_REQUEST_START;
  69 + case HTTP_REQUEST_GARBAGE:
  70 + if (httpRequestSkip(this)) {
  71 + this->cur_request = new(HttpRequest);
  72 + this->state = HTTP_REQUEST_START;
  73 + }
  74 + else {
  75 + cont = 0;
  76 + }
51 77 break;
52 78
53 79 case HTTP_REQUEST_START:
54   - if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) {
  80 + if (NULL == (line_end = getLine(this))) {
55 81 cont = 0;
56 82 break;
57 83 }
58 84
59   - httpRequestParserGetRequestLine(this->cur_request, line);
  85 + if (0 > httpRequestParserGetRequestLine(this, line_end)) {
  86 + ret = -1;
  87 + cont = 0;
  88 + break;
  89 + }
  90 +
  91 + len = line_end - this->buffer->buffer - this->buffer->bstart + 2;
  92 + this->buffer->bstart += len;
  93 + if (this->buffer->bstart >= this->buffer->bsize) {
  94 + this->buffer->bstart -= this->buffer->bsize;
  95 + }
  96 + this->buffer->bused -= len;
60 97
61 98 this->state = HTTP_REQUEST_REQUEST_LINE_DONE;
62 99 break;
63 100
64 101 case HTTP_REQUEST_REQUEST_LINE_DONE:
65   - if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) {
  102 + if (NULL == (line_end = getLine(this))) {
66 103 cont = 0;
67 104 break;
68 105 }
69 106
70   - if (0 == strlen(line)) {
  107 + if (0 == line_end - this->buffer->buffer - this->buffer->bstart) {
  108 + this->buffer->bstart += 2;
  109 + if (this->buffer->bstart >= this->buffer->bsize) {
  110 + this->buffer->bstart -= this->buffer->bsize;
  111 + }
  112 + this->buffer->bused -= 2;
  113 +
71 114 this->state = HTTP_REQUEST_HEADERS_DONE;
72 115 break;
73 116 }
74 117
75   - httpRequestParserGetHeader(this->cur_request, line);
  118 + httpRequestParserGetHeader(this, line_end);
  119 +
  120 + len = line_end - this->buffer->buffer - this->buffer->bstart + 2;
  121 + this->buffer->bstart += len;
  122 + if (this->buffer->bstart >= this->buffer->bsize) {
  123 + this->buffer->bstart -= this->buffer->bsize;
  124 + }
  125 + this->buffer->bused -= len;
  126 +
76 127 break;
77 128
78 129 case HTTP_REQUEST_HEADERS_DONE:
  130 + /**
  131 + * allocate memory according to content-length.
  132 + * If content length is to large reject request.
  133 + *
  134 + * @FUTURE check for multipart mime and handle it
  135 + * with temporary file.
  136 + */
79 137 httpRequestParserGetBody(this);
80 138 break;
81 139
82 140 case HTTP_REQUEST_DONE:
83   - /**
84   - * enqueue current request
85   - */
86 141 this->request_queue->msgs[(this->request_queue->nmsgs)++] =
87 142 (HttpMessage)this->cur_request;
88 143
89   - if (! httpMessageHasKeepAlive((HttpMessage)this->cur_request)) {
90   - ret = -2;
91   - }
92   -
  144 + ret = this->request_queue->nmsgs;
93 145 this->cur_request = NULL;
94 146
95   - /**
96   - * remove processed stuff from input buffer.
97   - */
98   - memmove(this->buffer, this->cur_data, REMAINS(this));
99   -
100   - this->buffer_used -= this->cur_data - this->buffer;
101   -
102   - /**
103   - * dont continue loop if input buffer is empty
104   - */
105   - if (0 == this->buffer_used) {
106   - cont = 0;
107   - }
108   -
109   - /**
110   - * prepare for next request
111   - */
112 147 this->state = HTTP_REQUEST_GARBAGE;
113 148
114 149 break;
... ... @@ -118,7 +153,7 @@ httpRequestParserParse(HttpRequestParser this)
118 153 }
119 154 }
120 155
121   - return this->request_queue->nmsgs;
  156 + return ret;
122 157 }
123 158
124 159 // vim: set ts=4 sw=4:
... ...
... ... @@ -3,46 +3,40 @@
3 3
4 4 #include "http/request/parser.h"
5 5
  6 +#define MAX(x,y) ((x) > (y) ? (x) : (y))
  7 +#define _BSIZE(x) (MAX((x),RESPONSE_WRITER_MAX_BUF))
  8 +#define BSIZE _BSIZE(this->nheader+message->nbody)
6 9
  10 +
  11 +/**
  12 + * @deprecated
  13 + */
7 14 ssize_t
8 15 httpRequestParserRead(HttpRequestParser this, int fd)
9 16 {
10   - size_t remaining, chunks;
11   - char buffer[1024];
  17 + size_t rsize;
  18 + ssize_t temp;
12 19
13   - ssize_t size = read(fd, buffer, 1024);
  20 + this->bend = (this->bsize == this->bend)?
  21 + 0 : this->bend;
14 22
15   - if (0 < size) {
16   - remaining = this->buffer_used % HTTP_REQUEST_PARSER_READ_CHUNK;
17   - remaining = HTTP_REQUEST_PARSER_READ_CHUNK - remaining;
18   - chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK;
  23 + rsize = (this->bstart <= this->bend)?
  24 + this->bsize - this->bend :
  25 + this->bstart - 1;
19 26
  27 + if (0 >= (temp = read(fd, &(this->buffer[this->bend]), rsize))) {
20 28 /**
21   - * because a division always rounds down
22   - * chunks holds exactly the currently allocated chunks if
23   - * remaining equals 0 but there is no space left.
24   - * Else chunks holds the actually allocated amount of chunks
25   - * minus 1.
26   - * For this reason chunks always has to be increased by 1.
  29 + * this means either we had an rsize of 0 what indicates that
  30 + * the buffer ran full without any processing took place or
  31 + * the connection was terminated in some way. In both cases
  32 + * we want to terminate the connection.
27 33 */
28   - chunks++;
29   -
30   - if (size >= remaining) {
31   - this->buffer =
32   - realloc(this->buffer, chunks * HTTP_REQUEST_PARSER_READ_CHUNK);
33   - }
34   -
35   - memcpy(this->buffer + this->buffer_used, buffer, size);
36   - this->buffer_used += size;
37   - this->buffer[this->buffer_used] = 0;
38   -
39   - size = httpRequestParserParse(this);
40   - }
41   - else {
42   - size = (0 == size)? -2 : size;
  34 + return (0 == temp)? -2 : -1;
43 35 }
44 36
45   - return size;
  37 + this->bend += temp;
  38 +
  39 + return temp;
46 40 }
47 41
48 42 // vim: set ts=4 sw=4:
... ...
1 1 #include <stdlib.h>
2 2 #include <string.h>
3 3 #include <stdio.h>
4   -#include <time.h>
5 4
6 5 #include "class.h"
7 6 #include "interface/class.h"
... ... @@ -23,8 +22,6 @@
23 22 HttpResponse
24 23 httpResponse404()
25 24 {
26   - time_t t;
27   - struct tm * tmp;
28 25 char buffer[200];
29 26 HttpResponse response;
30 27 HttpMessage message;
... ... @@ -46,12 +43,6 @@ httpResponse404()
46 43 httpHeaderAdd(&(message->header),
47 44 new(HttpHeader, "Content-Length", buffer));
48 45
49   - t = time(NULL);
50   - tmp = localtime(&t);
51   - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
52   - httpHeaderAdd(&(message->header),
53   - new(HttpHeader, "Date", buffer));
54   -
55 46 return response;
56 47 }
57 48
... ...
1 1 #include <stdlib.h>
2 2 #include <string.h>
3 3 #include <stdio.h>
4   -#include <time.h>
5 4 #include <sys/stat.h>
6 5 #include <fcntl.h>
7 6
... ... @@ -16,8 +15,6 @@
16 15 HttpResponse
17 16 httpResponseImage()
18 17 {
19   - time_t t;
20   - struct tm * tmp;
21 18 char buffer[200];
22 19 struct stat st;
23 20 HttpResponse response;
... ... @@ -40,12 +37,6 @@ httpResponseImage()
40 37 httpHeaderAdd(&(message->header),
41 38 new(HttpHeader, "Content-Length", buffer));
42 39
43   - t = time(NULL);
44   - tmp = localtime(&t);
45   - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
46   - httpHeaderAdd(&(message->header),
47   - new(HttpHeader, "Date", buffer));
48   -
49 40 return response;
50 41 }
51 42
... ...
1 1 #include <stdlib.h>
2 2 #include <string.h>
3 3 #include <stdio.h>
4   -#include <time.h>
5 4
6 5 #include "class.h"
7 6 #include "interface/class.h"
... ... @@ -23,8 +22,6 @@
23 22 HttpResponse
24 23 httpResponseMe()
25 24 {
26   - time_t t;
27   - struct tm * tmp;
28 25 char buffer[200];
29 26 HttpResponse response;
30 27 HttpMessage message;
... ... @@ -46,12 +43,6 @@ httpResponseMe()
46 43 httpHeaderAdd(&(message->header),
47 44 new(HttpHeader, "Content-Length", buffer));
48 45
49   - t = time(NULL);
50   - tmp = localtime(&t);
51   - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
52   - httpHeaderAdd(&(message->header),
53   - new(HttpHeader, "Date", buffer));
54   -
55 46 return response;
56 47 }
57 48
... ...
... ... @@ -21,7 +21,7 @@ httpResponseWriterWrite(HttpResponseWriter this, int fd)
21 21 {
22 22 HttpMessageQueue respq = this->response_queue;
23 23 HttpMessage message = (HttpMessage)this->cur_response;
24   - ssize_t processed = (message)? 1 : 0;
  24 + ssize_t processed = (message)? 1 : 0;
25 25 int cont = 1;
26 26
27 27 while (cont) {
... ... @@ -74,7 +74,6 @@ httpResponseWriterWrite(HttpResponseWriter this, int fd)
74 74 &(this->pipe[this->pend]),
75 75 &(message->body[this->nbuffer]),
76 76 temp);
77   -
78 77 break;
79 78
80 79 case HTTP_MESSAGE_PIPED:
... ...
  1 +#include <stdlib.h>
1 2 #include <stdarg.h>
  3 +#include <string.h>
2 4
3 5 #include "class.h"
4 6 #include "http/worker.h"
... ... @@ -9,13 +11,19 @@
9 11 #include "interface/stream_reader.h"
10 12 #include "interface/stream_writer.h"
11 13
  14 +#define SHMN "/worker_"
12 15 static
13 16 void
14 17 ctor(void * _this, va_list * params)
15 18 {
16 19 HttpWorker this = _this;
  20 + char id[sizeof(SHMN) + 15 + 5];
17 21
18   - this->parser = new(HttpRequestParser);
  22 + this->remoteAddr = va_arg(*params, char *);
  23 + this->handle = va_arg(*params, int);
  24 + sprintf(id, SHMN "%s_%05d", this->remoteAddr, this->handle);
  25 +
  26 + this->parser = new(HttpRequestParser, id);
19 27 this->writer = new(HttpResponseWriter);
20 28 }
21 29
... ... @@ -29,20 +37,7 @@ dtor(void * _this)
29 37 delete(&this->writer);
30 38 }
31 39
32   -static
33   -void
34   -_clone(void * _this, void * _base)
35   -{
36   - /**
37   - * TODO: this actually simply creates a new worker
38   - * and ignores the base. Think about this.
39   - */
40   - va_list foo;
41   -
42   - ctor(_this, &foo);
43   -}
44   -
45   -INIT_IFACE(Class, ctor, dtor, _clone);
  40 +INIT_IFACE(Class, ctor, dtor, NULL);
46 41 INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpWorkerProcess);
47 42 INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpWorkerWrite);
48 43 CREATE_CLASS(
... ...
  1 +#include <time.h>
  2 +
1 3 #include "class.h"
2 4 #include "interface/class.h"
3 5
4 6 #include "http/worker.h"
5 7 #include "http/request/parser.h"
  8 +#include "http/header.h"
  9 +#include "http/request.h"
  10 +#include "http/message.h"
6 11
7 12 ssize_t
8 13 httpWorkerProcess(HttpWorker this, int fd)
9 14 {
10   - ssize_t size;
  15 + time_t t;
  16 + struct tm * tmp;
  17 + char buffer[200];
  18 + ssize_t size;
11 19
12   - if (0 < (size = httpRequestParserRead(this->parser, fd))) {
  20 + if (0 < (size = httpRequestParserParse(this->parser, fd))) {
13 21 int i;
14 22 HttpMessageQueue reqq = this->parser->request_queue;
15 23 HttpMessageQueue respq = this->writer->response_queue;
... ... @@ -19,8 +27,8 @@ httpWorkerProcess(HttpWorker this, int fd)
19 27 * @TODO: for now simply remove request and send not found.
20 28 * Make this sane.
21 29 */
22   - HttpRequest request = (HttpRequest)(reqq->msgs[i]);
23   - HttpMessage response = NULL;
  30 + HttpRequest request = (HttpRequest)(reqq->msgs[i]);
  31 + HttpMessage response = NULL;
24 32
25 33 if (0 == strcmp("GET", request->method) &&
26 34 0 == strcmp("/me/", request->uri)) {
... ... @@ -45,12 +53,19 @@ httpWorkerProcess(HttpWorker this, int fd)
45 53 new(HttpHeader, "Connection", "Close"));
46 54 }
47 55
  56 + t = time(NULL);
  57 + tmp = localtime(&t);
  58 + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
  59 + httpHeaderAdd(&(response->header),
  60 + new(HttpHeader, "Date", buffer));
  61 +
48 62 respq->msgs[(respq->nmsgs)++] = response;
49 63 response = NULL;
50 64 delete(&(reqq->msgs[i]));
51 65 }
52 66
53 67 reqq->nmsgs = 0;
  68 + size = respq->nmsgs;
54 69 }
55 70
56 71 return size;
... ...
  1 +#include <stdio.h>
  2 +
  3 +#include "ringbuffer.h"
  4 +#include "interface/class.h"
  5 +
  6 +int
  7 +main()
  8 +{
  9 + Ringbuffer buf = new(Ringbuffer, "/rbtest", 1);
  10 +
  11 + strcpy(buf->buffer + buf->bsize - 5, "Dies ist ein foobar test");
  12 +
  13 + printf("%s\n", buf->buffer);
  14 + printf("%s\n", buf->buffer + buf->bsize - 5);
  15 +
  16 + delete(&buf);
  17 +
  18 + return 0;
  19 +}
  20 +
  21 +// vim: set ts=4 sw=4:
... ...
  1 +#define _POSIX_SOURCE
  2 +#define _POSIX_C_SOURCE 200112L
  3 +
  4 +#include <sys/types.h>
  5 +#include <sys/stat.h>
  6 +#include <sys/mman.h>
  7 +#include <stdarg.h>
  8 +#include <stdlib.h>
  9 +#include <string.h>
  10 +#include <unistd.h>
  11 +#include <fcntl.h>
  12 +
  13 +#include "class.h"
  14 +#include "interface/class.h"
  15 +
  16 +#include "ringbuffer.h"
  17 +
  18 +#define PAGES(size, psize) ((size)/(psize)+(0 == (size)%(psize))?0:1)
  19 +
  20 +
  21 +static void dtor(void*);
  22 +
  23 +static
  24 +void
  25 +ctor(void * _this, va_list * params)
  26 +{
  27 + Ringbuffer this = _this;
  28 + char state = 0;
  29 + char * shm_name = va_arg(*params, char*);
  30 + long psize = sysconf(_SC_PAGESIZE);
  31 + size_t size;
  32 + int shm;
  33 + void * shm_addr;
  34 +
  35 + this->shm_name = malloc(strlen(shm_name) + 1);
  36 + strcpy(this->shm_name, shm_name);
  37 +
  38 + /**
  39 + * align size at page boundary.
  40 + * increase as neccessary
  41 + */
  42 + size = va_arg(*params, size_t);
  43 + size = (0 <= size)? 1 : size;
  44 + this->bsize = psize * PAGES(size, psize);
  45 +
  46 + while (0 == state) {
  47 + shm = shm_open(this->shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
  48 + if (-1 == shm) {
  49 + break;
  50 + }
  51 + else {
  52 + ftruncate(shm, this->bsize);
  53 + }
  54 +
  55 + shm_addr = mmap (0, this->bsize<<1,
  56 + PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
  57 + if (shm_addr == MAP_FAILED)
  58 + break;
  59 +
  60 + munmap(shm_addr, this->bsize<<1);
  61 +
  62 + this->buffer = mmap (shm_addr, this->bsize,
  63 + PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
  64 + if (this->buffer == MAP_FAILED) {
  65 + shm_addr = NULL;
  66 + break;
  67 + }
  68 +
  69 + this->mirror = mmap (shm_addr + this->bsize, this->bsize,
  70 + PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
  71 + if (this->mirror != shm_addr + this->bsize) {
  72 + shm_addr = NULL;
  73 + break;
  74 + }
  75 +
  76 + state = 1;
  77 + }
  78 +
  79 + if (-1 != shm) {
  80 + shm_unlink(this->shm_name);
  81 + close(shm);
  82 + }
  83 +
  84 + if (1 != state) {
  85 + if (shm_addr) {
  86 + munmap(shm_addr, this->bsize<<1);
  87 + }
  88 +
  89 + dtor(this);
  90 + }
  91 +}
  92 +
  93 +static
  94 +void
  95 +dtor(void * _this)
  96 +{
  97 + Ringbuffer this = _this;
  98 +
  99 + if (NULL != this->shm_name) {
  100 + free(this->shm_name);
  101 + }
  102 +
  103 + if (this->buffer) {
  104 + munmap(this->buffer, this->bsize);
  105 + this->buffer = NULL;
  106 + }
  107 +
  108 + if (this->mirror) {
  109 + munmap(this->mirror, this->bsize);
  110 + this->mirror = NULL;
  111 + }
  112 +}
  113 +
  114 +INIT_IFACE(Class, ctor, dtor, NULL);
  115 +CREATE_CLASS(Ringbuffer, NULL, IFACE(Class));
  116 +
  117 +// vim: set ts=4 sw=4:
... ...
  1 +#include <sys/types.h>
  2 +#include <unistd.h>
  3 +#include <errno.h>
  4 +
  5 +#include "ringbuffer.h"
  6 +
  7 +ssize_t
  8 +rbRead(Ringbuffer this, int fd)
  9 +{
  10 + ssize_t rrsize = 0;
  11 + size_t rsize = this->bsize - this->bused;
  12 +
  13 + if (0 == rsize) {
  14 + errno = ERBOVRFL;
  15 + return -1;
  16 + }
  17 +
  18 + rrsize = read(fd, this->buffer + this->bend, rsize);
  19 +
  20 + switch (rrsize) {
  21 + case 0:
  22 + rsize = -2;
  23 +
  24 + case -1:
  25 + break;
  26 +
  27 + default:
  28 + this->bend += rrsize;
  29 + this->bused += rrsize;
  30 +
  31 + if (this->bend >= this->bsize) {
  32 + this->bend -= this->bsize;
  33 + }
  34 +
  35 + break;
  36 + }
  37 +
  38 + return rrsize;
  39 +}
  40 +
  41 +// vim: set ts=4 sw=4:
... ...
1 1 #include <errno.h>
2 2
  3 +#include "http/worker.h"
  4 +
3 5 static
4 6 int
5 7 serverHandleAccept(Server this)
6 8 {
7   - char remoteAddr[16] = "";
  9 + char remoteAddr[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
8 10 Sock acc;
9 11
10   - acc = socketAccept(this->sock, remoteAddr);
  12 + acc = socketAccept(this->sock, &remoteAddr);
11 13
12 14 if (-1 != acc->handle) {
13 15 //* save the socket handle
14 16 (this->conns)[acc->handle].sock = acc;
15 17
16 18 //* clone reader
17   - (this->conns)[acc->handle].worker = clone(this->worker);
  19 + (this->conns)[acc->handle].worker = new(HttpWorker, remoteAddr, acc->handle);
18 20
19 21 (this->fds)[this->nfds].fd = acc->handle;
20 22 (this->fds)[this->nfds].events = POLLIN;
... ...
... ... @@ -6,7 +6,7 @@
6 6 #include "interface/logger.h"
7 7
8 8 Sock
9   -socketAccept(Sock this, char remoteAddr[16])
  9 +socketAccept(Sock this, char (*remoteAddr)[])
10 10 {
11 11 Sock sock; /* Socket for client */
12 12 unsigned int len; /* Length of client address data structure */
... ... @@ -33,8 +33,9 @@ socketAccept(Sock this, char remoteAddr[16])
33 33 loggerLog(this->log, LOGGER_WARNING,
34 34 "error accepting connection: %s", strerror(errno));
35 35 } else {
  36 + memcpy(*remoteAddr, inet_ntoa((sock->addr).sin_addr), 15);
36 37 loggerLog(this->log, LOGGER_INFO,
37   - "handling client %s\n", inet_ntoa((sock->addr).sin_addr));
  38 + "handling client %s\n", *remoteAddr);
38 39 }
39 40
40 41 return sock;
... ...
... ... @@ -19,7 +19,7 @@ int
19 19 main()
20 20 {
21 21 Logger logger = new(LoggerSyslog, LOGGER_ERR);
22   - HttpWorker worker = new(HttpWorker);
  22 + HttpWorker worker = new(HttpWorker, "", 0);
23 23 Server server = new(Server, logger, worker, 11212, SOMAXCONN);
24 24
25 25 struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
... ...
Please register or login to post a comment