Commit f678adcae4b89de9558cfd023e3bc678853bee9d
1 parent
ca023b99
access to headers via hash, read body (actually only with content-length header …
…should also look for content-encoding)
Showing
6 changed files
with
101 additions
and
8 deletions
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