Browse Source

access to headers via hash, read body (actually only with content-length header should also look for content-encoding)

master
Georg Hopp 14 years ago
parent
commit
f678adcae4
  1. 26
      ChangeLog
  2. 13
      include/http/request.h
  3. 2
      src/Makefile.am
  4. 61
      src/http/request_parser.c
  5. 5
      src/server/run.c
  6. 2
      src/testserver.c

26
ChangeLog

@ -1,6 +1,30 @@
2012-02-09 09:34:21 +0100 Georg Hopp
* access to headers via hash, read body (actually only with content-length header should also look for content-encoding) (HEAD, master)
2012-02-08 16:51:49 +0100 Georg Hopp
* fix handling of remote close - i should have another eye on this...there still seems to be something wrong.
2012-02-08 15:04:52 +0100 Georg Hopp
* fixed some warnings
2012-02-08 13:12:59 +0100 Georg Hopp
* changed documentation
2012-02-08 13:05:23 +0100 Georg Hopp
* added first generated documentation
2012-02-08 12:14:44 +0100 Georg Hopp
* oops commit...forgot to add request_queue.c
2012-02-08 11:52:30 +0100 Georg Hopp
* found the file handle lost...made a first workaround and added an todo. (HEAD, master)
* found the file handle lost...made a first workaround and added an todo.
2012-02-08 10:21:04 +0100 Georg Hopp

13
include/http/request.h

@ -8,15 +8,20 @@ CLASS(HttpRequest) {
char * uri;
char * method;
struct {
char * name;
char * value;
struct HttpRequestHeader {
unsigned long hash;
char * name;
char * value;
} header[128];
int nheader;
char * body;
char done;
int nbody;
};
char *
httpRequestHeaderGet(HttpRequest this, const char * name);
#endif /* __HTTP_REQUEST_H__ */
// vim: set ts=4 sw=4:

2
src/Makefile.am

@ -5,7 +5,7 @@ CLASS = class.c interface.c interface/class.c
SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
SERVER = server.c server/run.c server/close_conn.c
LOGGER = logger.c logger/stderr.c logger/syslog.c interface/logger.c
HTTP = interface/stream_reader.c http/request_parser.c http/request.c http/request_queue.c
HTTP = interface/stream_reader.c http/request_parser.c http/request.c http/request_queue.c http/request/header_get.c
AM_CFLAGS = -Wall -I ../include/

61
src/http/request_parser.c

@ -129,6 +129,43 @@ httpRequestSkip(char ** data)
for (; 0 != **data && ! isalpha(**data); (*data)++);
}
/**
* SDBM hashing algorithm:
*
* this algorithm was created for sdbm (a public-domain reimplementation of
* ndbm) database library. it was found to do well in scrambling bits,
* causing better distribution of the keys and fewer splits. it also happens
* to be a good general hashing function with good distribution. the actual
* function is hash(i) = hash(i - 1) * 65599 + str[i]; what is included below
* is the faster version used in gawk. [there is even a faster, duff-device
* version] the magic constant 65599 was picked out of thin air while
* experimenting with different constants, and turns out to be a prime. this
* is one of the algorithms used in berkeley db (see sleepycat) and elsewhere.
*/
static
inline
unsigned long
sdbm(unsigned char * str)
{
unsigned long hash = 0;
int c;
while ((c = *str++))
hash = c + (hash << 6) + (hash << 16) - hash;
return hash;
}
static
inline
int
comp (const void * _a, const void * _b)
{
const struct HttpRequestHeader * a = _a;
const struct HttpRequestHeader * b = _b;
return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
}
static
void
httpRequestParserParse(HttpRequestParser this)
@ -207,21 +244,43 @@ httpRequestParserParse(HttpRequestParser this)
*delim = 0;
(request->header)[header_idx].name = malloc(strlen(line) + 1);
strcpy((request->header)[header_idx].name, line);
(request->header)[header_idx].hash = sdbm((unsigned char *)line);
line = delim + 1;
for (; *line == ' ' && *line != 0; line++);
(request->header)[header_idx].value = malloc(strlen(line) + 1);
strcpy((request->header)[header_idx].value, line);
header_idx++;
request->nheader++;
}
header_idx++;
break;
case HTTP_REQUEST_HEADERS_DONE:
/**
* @TODO: here comes the body handling
*/
qsort(
request->header,
request->nheader,
sizeof(struct HttpRequestHeader),
comp);
{
char * bodylen;
bodylen = httpRequestHeaderGet(request, "Content-Length");
if (NULL != bodylen) {
request->nbody = atoi(bodylen);
request->body = calloc(1, request->nbody + 1);
memcpy(request->body, data, request->nbody);
data += request->nbody;
}
}
this->state = HTTP_REQUEST_DONE;
break;

5
src/server/run.c

@ -80,6 +80,11 @@ serverRun(Server this)
for (j=0; j<queue->nrequests; j++) {
HttpRequest request = queue->requests[j];
if (NULL != request->body) {
puts("==REQUEST BODY==");
puts(request->body);
}
/**
* @TODO: for now simply remove request and send not found.
* Make this sane.

2
src/testserver.c

@ -13,7 +13,7 @@
int
main()
{
Logger logger = new(LoggerStderr, LOGGER_INFO);
Logger logger = new(LoggerStderr, LOGGER_ERR);
HttpRequestParser parser = new(HttpRequestParser);
Server server = new(Server, logger, parser, 11212, SOMAXCONN);
//Server server = new(Server, logger, parser, 11212, 20);

Loading…
Cancel
Save