Commit f678adcae4b89de9558cfd023e3bc678853bee9d

Authored by Georg Hopp
1 parent ca023b99

access to headers via hash, read body (actually only with content-length header …

…should also look for content-encoding)
  1 +2012-02-09 09:34:21 +0100 Georg Hopp
  2 +
  3 + * access to headers via hash, read body (actually only with content-length header should also look for content-encoding) (HEAD, master)
  4 +
  5 +2012-02-08 16:51:49 +0100 Georg Hopp
  6 +
  7 + * fix handling of remote close - i should have another eye on this...there still seems to be something wrong.
  8 +
  9 +2012-02-08 15:04:52 +0100 Georg Hopp
  10 +
  11 + * fixed some warnings
  12 +
  13 +2012-02-08 13:12:59 +0100 Georg Hopp
  14 +
  15 + * changed documentation
  16 +
  17 +2012-02-08 13:05:23 +0100 Georg Hopp
  18 +
  19 + * added first generated documentation
  20 +
  21 +2012-02-08 12:14:44 +0100 Georg Hopp
  22 +
  23 + * oops commit...forgot to add request_queue.c
  24 +
1 2012-02-08 11:52:30 +0100 Georg Hopp 25 2012-02-08 11:52:30 +0100 Georg Hopp
2 26
3 - * found the file handle lost...made a first workaround and added an todo. (HEAD, master) 27 + * found the file handle lost...made a first workaround and added an todo.
4 28
5 2012-02-08 10:21:04 +0100 Georg Hopp 29 2012-02-08 10:21:04 +0100 Georg Hopp
6 30
@@ -8,15 +8,20 @@ CLASS(HttpRequest) { @@ -8,15 +8,20 @@ CLASS(HttpRequest) {
8 char * uri; 8 char * uri;
9 char * method; 9 char * method;
10 10
11 - struct {  
12 - char * name;  
13 - char * value; 11 + struct HttpRequestHeader {
  12 + unsigned long hash;
  13 + char * name;
  14 + char * value;
14 } header[128]; 15 } header[128];
  16 + int nheader;
15 17
16 char * body; 18 char * body;
17 - char done; 19 + int nbody;
18 }; 20 };
19 21
  22 +char *
  23 +httpRequestHeaderGet(HttpRequest this, const char * name);
  24 +
20 #endif /* __HTTP_REQUEST_H__ */ 25 #endif /* __HTTP_REQUEST_H__ */
21 26
22 // vim: set ts=4 sw=4: 27 // vim: set ts=4 sw=4:
@@ -5,7 +5,7 @@ CLASS = class.c interface.c interface/class.c @@ -5,7 +5,7 @@ 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 http/request.c http/request_queue.c 8 +HTTP = interface/stream_reader.c http/request_parser.c http/request.c http/request_queue.c http/request/header_get.c
9 9
10 AM_CFLAGS = -Wall -I ../include/ 10 AM_CFLAGS = -Wall -I ../include/
11 11
@@ -129,6 +129,43 @@ httpRequestSkip(char ** data) @@ -129,6 +129,43 @@ httpRequestSkip(char ** data)
129 for (; 0 != **data && ! isalpha(**data); (*data)++); 129 for (; 0 != **data && ! isalpha(**data); (*data)++);
130 } 130 }
131 131
  132 +/**
  133 + * SDBM hashing algorithm:
  134 + *
  135 + * this algorithm was created for sdbm (a public-domain reimplementation of
  136 + * ndbm) database library. it was found to do well in scrambling bits,
  137 + * causing better distribution of the keys and fewer splits. it also happens
  138 + * to be a good general hashing function with good distribution. the actual
  139 + * function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
  140 + * is the faster version used in gawk. [there is even a faster, duff-device
  141 + * version] the magic constant 65599 was picked out of thin air while
  142 + * experimenting with different constants, and turns out to be a prime. this
  143 + * is one of the algorithms used in berkeley db (see sleepycat) and elsewhere.
  144 + */
  145 +static
  146 +inline
  147 +unsigned long
  148 +sdbm(unsigned char * str)
  149 +{
  150 + unsigned long hash = 0;
  151 + int c;
  152 +
  153 + while ((c = *str++))
  154 + hash = c + (hash << 6) + (hash << 16) - hash;
  155 +
  156 + return hash;
  157 +}
  158 +
  159 +static
  160 +inline
  161 +int
  162 +comp (const void * _a, const void * _b)
  163 +{
  164 + const struct HttpRequestHeader * a = _a;
  165 + const struct HttpRequestHeader * b = _b;
  166 + return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
  167 +}
  168 +
132 static 169 static
133 void 170 void
134 httpRequestParserParse(HttpRequestParser this) 171 httpRequestParserParse(HttpRequestParser this)
@@ -207,21 +244,43 @@ httpRequestParserParse(HttpRequestParser this) @@ -207,21 +244,43 @@ httpRequestParserParse(HttpRequestParser this)
207 *delim = 0; 244 *delim = 0;
208 (request->header)[header_idx].name = malloc(strlen(line) + 1); 245 (request->header)[header_idx].name = malloc(strlen(line) + 1);
209 strcpy((request->header)[header_idx].name, line); 246 strcpy((request->header)[header_idx].name, line);
  247 + (request->header)[header_idx].hash = sdbm((unsigned char *)line);
210 248
211 line = delim + 1; 249 line = delim + 1;
212 for (; *line == ' ' && *line != 0; line++); 250 for (; *line == ' ' && *line != 0; line++);
213 251
214 (request->header)[header_idx].value = malloc(strlen(line) + 1); 252 (request->header)[header_idx].value = malloc(strlen(line) + 1);
215 strcpy((request->header)[header_idx].value, line); 253 strcpy((request->header)[header_idx].value, line);
  254 +
  255 + header_idx++;
  256 + request->nheader++;
216 } 257 }
217 258
218 - header_idx++;  
219 break; 259 break;
220 260
221 case HTTP_REQUEST_HEADERS_DONE: 261 case HTTP_REQUEST_HEADERS_DONE:
222 /** 262 /**
223 * @TODO: here comes the body handling 263 * @TODO: here comes the body handling
224 */ 264 */
  265 + qsort(
  266 + request->header,
  267 + request->nheader,
  268 + sizeof(struct HttpRequestHeader),
  269 + comp);
  270 +
  271 + {
  272 + char * bodylen;
  273 +
  274 + bodylen = httpRequestHeaderGet(request, "Content-Length");
  275 +
  276 + if (NULL != bodylen) {
  277 + request->nbody = atoi(bodylen);
  278 + request->body = calloc(1, request->nbody + 1);
  279 + memcpy(request->body, data, request->nbody);
  280 + data += request->nbody;
  281 + }
  282 + }
  283 +
225 this->state = HTTP_REQUEST_DONE; 284 this->state = HTTP_REQUEST_DONE;
226 break; 285 break;
227 286
@@ -80,6 +80,11 @@ serverRun(Server this) @@ -80,6 +80,11 @@ serverRun(Server this)
80 for (j=0; j<queue->nrequests; j++) { 80 for (j=0; j<queue->nrequests; j++) {
81 HttpRequest request = queue->requests[j]; 81 HttpRequest request = queue->requests[j];
82 82
  83 + if (NULL != request->body) {
  84 + puts("==REQUEST BODY==");
  85 + puts(request->body);
  86 + }
  87 +
83 /** 88 /**
84 * @TODO: for now simply remove request and send not found. 89 * @TODO: for now simply remove request and send not found.
85 * Make this sane. 90 * Make this sane.
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 int 13 int
14 main() 14 main()
15 { 15 {
16 - Logger logger = new(LoggerStderr, LOGGER_INFO); 16 + Logger logger = new(LoggerStderr, LOGGER_ERR);
17 HttpRequestParser parser = new(HttpRequestParser); 17 HttpRequestParser parser = new(HttpRequestParser);
18 Server server = new(Server, logger, parser, 11212, SOMAXCONN); 18 Server server = new(Server, logger, parser, 11212, SOMAXCONN);
19 //Server server = new(Server, logger, parser, 11212, 20); 19 //Server server = new(Server, logger, parser, 11212, 20);
Please register or login to post a comment