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 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 29 2012-02-08 10:21:04 +0100 Georg Hopp
6 30
... ...
... ... @@ -8,15 +8,20 @@ CLASS(HttpRequest) {
8 8 char * uri;
9 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 15 } header[128];
  16 + int nheader;
15 17
16 18 char * body;
17   - char done;
  19 + int nbody;
18 20 };
19 21
  22 +char *
  23 +httpRequestHeaderGet(HttpRequest this, const char * name);
  24 +
20 25 #endif /* __HTTP_REQUEST_H__ */
21 26
22 27 // vim: set ts=4 sw=4:
... ...
... ... @@ -5,7 +5,7 @@ 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 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 10 AM_CFLAGS = -Wall -I ../include/
11 11
... ...
... ... @@ -129,6 +129,43 @@ httpRequestSkip(char ** data)
129 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 169 static
133 170 void
134 171 httpRequestParserParse(HttpRequestParser this)
... ... @@ -207,21 +244,43 @@ httpRequestParserParse(HttpRequestParser this)
207 244 *delim = 0;
208 245 (request->header)[header_idx].name = malloc(strlen(line) + 1);
209 246 strcpy((request->header)[header_idx].name, line);
  247 + (request->header)[header_idx].hash = sdbm((unsigned char *)line);
210 248
211 249 line = delim + 1;
212 250 for (; *line == ' ' && *line != 0; line++);
213 251
214 252 (request->header)[header_idx].value = malloc(strlen(line) + 1);
215 253 strcpy((request->header)[header_idx].value, line);
  254 +
  255 + header_idx++;
  256 + request->nheader++;
216 257 }
217 258
218   - header_idx++;
219 259 break;
220 260
221 261 case HTTP_REQUEST_HEADERS_DONE:
222 262 /**
223 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 284 this->state = HTTP_REQUEST_DONE;
226 285 break;
227 286
... ...
... ... @@ -80,6 +80,11 @@ serverRun(Server this)
80 80 for (j=0; j<queue->nrequests; j++) {
81 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 89 * @TODO: for now simply remove request and send not found.
85 90 * Make this sane.
... ...
... ... @@ -13,7 +13,7 @@
13 13 int
14 14 main()
15 15 {
16   - Logger logger = new(LoggerStderr, LOGGER_INFO);
  16 + Logger logger = new(LoggerStderr, LOGGER_ERR);
17 17 HttpRequestParser parser = new(HttpRequestParser);
18 18 Server server = new(Server, logger, parser, 11212, SOMAXCONN);
19 19 //Server server = new(Server, logger, parser, 11212, 20);
... ...
Please register or login to post a comment