Commit 9f801ba422f35a2f864bd707de35daca8482d6dd
1 parent
ac6873fe
changed all string operation within header handling with fixed length mem operat…
…ions, preventing multiple iterations over these strings. In theory this should improve performance in reality it seems that it is worse...CHECK WHY
Showing
25 changed files
with
264 additions
and
130 deletions
1 | +2012-02-23 13:02:23 +0100 Georg Hopp | |
2 | + | |
3 | + * changed all string operation within header handling with fixed length mem operations, preventing multiple iterations over these strings. In theory this should improve performance in reality it seems that it is worse...CHECK WHY (HEAD, master) | |
4 | + | |
5 | +2012-02-23 00:05:25 +0100 Georg Hopp | |
6 | + | |
7 | + * fix initialization of search value | |
8 | + | |
9 | +2012-02-22 21:50:21 +0100 Georg Hopp | |
10 | + | |
11 | + * ed | |
12 | + | |
1 | 13 | 2012-02-22 21:49:52 +0100 Georg Hopp |
2 | 14 | |
3 | - * structural changes for worker/process. @TODO actually i have no idea why this happens. (HEAD, master) | |
15 | + * structural changes for worker/process. @TODO actually i have no idea why this happens. | |
4 | 16 | |
5 | 17 | 2012-02-22 12:19:40 +0100 Georg Hopp |
6 | 18 | ... | ... |
... | ... | @@ -62,7 +62,7 @@ CLASS(Cbuf) { |
62 | 62 | ssize_t cbufRead(Cbuf, int fd); |
63 | 63 | ssize_t cbufWrite(Cbuf, int fd); |
64 | 64 | |
65 | -char * cbufGetLine(Cbuf); | |
65 | +char * cbufGetLine(Cbuf, char **); | |
66 | 66 | char * cbufGetData(Cbuf, size_t); |
67 | 67 | char * cbufSetData(Cbuf, const void *, size_t); |
68 | 68 | void cbufEmpty(Cbuf); | ... | ... |
... | ... | @@ -25,21 +25,25 @@ |
25 | 25 | #ifndef __HTTP_HEADER_H__ |
26 | 26 | #define __HTTP_HEADER_H__ |
27 | 27 | |
28 | +#include <sys/types.h> | |
29 | + | |
28 | 30 | #include "class.h" |
29 | 31 | |
30 | -#define HTTP_HEADER_VALUE_CHUNK_SIZE 128 | |
32 | +#define N_VALUES 128 | |
31 | 33 | |
32 | 34 | CLASS(HttpHeader) { |
33 | 35 | unsigned long hash; |
34 | 36 | char * name; |
35 | - char * value[HTTP_HEADER_VALUE_CHUNK_SIZE]; | |
36 | - size_t nvalue; | |
37 | + char * value[N_VALUES]; | |
38 | + size_t nname; //!< len of name without \0 | |
39 | + size_t nvalue[N_VALUES]; //!< len of value without \0 | |
40 | + size_t cvalue; //!< count of values up to N_VALUE | |
37 | 41 | }; |
38 | 42 | |
39 | 43 | HttpHeader httpHeaderParse(char * line); // @INFO: destructive |
40 | 44 | |
41 | 45 | HttpHeader httpHeaderAdd(const HttpHeader *, HttpHeader); |
42 | -HttpHeader httpHeaderGet(const HttpHeader *, const char *); | |
46 | +HttpHeader httpHeaderGet(const HttpHeader *, const char *, size_t); | |
43 | 47 | size_t httpHeaderSizeGet(HttpHeader); |
44 | 48 | size_t httpHeaderToString(HttpHeader, char *); |
45 | 49 | ... | ... |
... | ... | @@ -63,9 +63,8 @@ CLASS(HttpRequestParser) { |
63 | 63 | ssize_t httpRequestParserParse(HttpRequestParser, int); |
64 | 64 | void httpRequestParserGetBody(HttpRequestParser); |
65 | 65 | |
66 | -ssize_t httpRequestParserGetRequestLine(HttpRequestParser, char *); | |
67 | -ssize_t httpRequestParserGetHeader(HttpRequestParser, char *); | |
68 | -void httpRequestParserGetBody(HttpRequestParser); | |
66 | +void httpRequestParserGetRequestLine(HttpRequest, char *); | |
67 | +void httpRequestParserGetHeader(HttpRequest, char *, char *); | |
69 | 68 | |
70 | 69 | #endif // __HTTP_REQUEST_PARSER_H__ |
71 | 70 | ... | ... |
... | ... | @@ -38,10 +38,16 @@ CLASS(HttpResponse) { |
38 | 38 | char * reason; |
39 | 39 | }; |
40 | 40 | |
41 | -HttpResponse httpResponse304(const char *, const char *, const char *); | |
41 | +HttpResponse httpResponse304( | |
42 | + const char *, size_t, | |
43 | + const char *, size_t, | |
44 | + const char *, size_t); | |
42 | 45 | HttpResponse httpResponse404(); |
43 | 46 | HttpResponse httpResponseMe(int); |
44 | -HttpResponse httpResponseAsset(const char *, const char *, const char *); | |
47 | +HttpResponse httpResponseAsset( | |
48 | + const char *, | |
49 | + const char *, size_t, | |
50 | + const char *, size_t); | |
45 | 51 | |
46 | 52 | #endif // __HTTP_RESPONSE_H__ |
47 | 53 | ... | ... |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | #include "cbuf.h" |
28 | 28 | |
29 | 29 | char * |
30 | -cbufGetLine(Cbuf this) | |
30 | +cbufGetLine(Cbuf this, char ** line_end) | |
31 | 31 | { |
32 | 32 | char * nl = cbufMemchr(this, '\n'); |
33 | 33 | char * ret = NULL; |
... | ... | @@ -35,8 +35,9 @@ cbufGetLine(Cbuf this) |
35 | 35 | if (NULL != nl) { |
36 | 36 | size_t len = cbufAddrIndex(this, nl) + 1; |
37 | 37 | |
38 | - *nl = 0; | |
39 | - *(nl-1) = ('\r' == *(nl-1))? 0 : *(nl-1); | |
38 | + *line_end = nl - 1; | |
39 | + *nl = 0; | |
40 | + *(nl-1) = ('\r' == *(nl-1))? 0 : *(nl-1); | |
40 | 41 | |
41 | 42 | ret = cbufGetRead(this); |
42 | 43 | cbufIncRead(this, len); | ... | ... |
... | ... | @@ -38,16 +38,19 @@ httpHeaderCtor(void * _this, va_list * params) { |
38 | 38 | char * name; |
39 | 39 | char * value; |
40 | 40 | |
41 | - name = va_arg(* params, char *); | |
42 | - value = va_arg(* params, char *); | |
41 | + name = va_arg(* params, char *); | |
42 | + this->nname = va_arg(* params, size_t); | |
43 | + value = va_arg(* params, char *); | |
44 | + this->nvalue[0] = va_arg(* params, size_t); | |
43 | 45 | |
44 | - this->name = malloc(strlen(name) + 1); | |
45 | - strcpy(this->name, name); | |
46 | + this->name = malloc(this->nname); | |
47 | + memcpy(this->name, name, this->nname); | |
46 | 48 | |
47 | - this->hash = sdbm((unsigned char *)name); | |
49 | + this->hash = sdbm((unsigned char *)name, this->nname); | |
48 | 50 | |
49 | - (this->value)[this->nvalue] = malloc(strlen(value) + 1); | |
50 | - strcpy((this->value)[this->nvalue++], value); | |
51 | + (this->value)[0] = malloc((this->nvalue)[0]); | |
52 | + memcpy((this->value)[0], value, (this->nvalue)[0]); | |
53 | + this->cvalue = 1; | |
51 | 54 | |
52 | 55 | return 0; |
53 | 56 | } |
... | ... | @@ -61,7 +64,7 @@ httpHeaderDtor(void * _this) |
61 | 64 | |
62 | 65 | FREE(this->name); |
63 | 66 | |
64 | - for (i=0; i<this->nvalue; i++) { | |
67 | + for (i=0; i<this->cvalue; i++) { | |
65 | 68 | FREE(this->value[i]); |
66 | 69 | } |
67 | 70 | } | ... | ... |
... | ... | @@ -43,18 +43,26 @@ comp(const void * _a, const void * _b) |
43 | 43 | HttpHeader |
44 | 44 | httpHeaderAdd(const HttpHeader * root, HttpHeader header) |
45 | 45 | { |
46 | - HttpHeader * found = tsearch(header, (void **)root, comp); | |
46 | + HttpHeader * _found = tsearch(header, (void **)root, comp); | |
47 | + HttpHeader found; | |
48 | + | |
49 | + if (NULL == _found) { | |
50 | + return NULL; | |
51 | + } | |
52 | + | |
53 | + found = *_found; | |
47 | 54 | |
48 | - if (*found != header) { | |
49 | - if ((*found)->nvalue >= HTTP_HEADER_VALUE_CHUNK_SIZE) { | |
55 | + if (found != header) { | |
56 | + if (found->cvalue >= N_VALUES) { | |
50 | 57 | return NULL; |
51 | 58 | } |
52 | - (*found)->value[(*found)->nvalue++] = (header->value)[0]; | |
59 | + (found->nvalue)[found->cvalue] = (header->nvalue)[0]; | |
60 | + (found->value)[(found->cvalue)++] = (header->value)[0]; | |
53 | 61 | (header->value)[0] = NULL; |
54 | 62 | delete(header); |
55 | 63 | } |
56 | 64 | |
57 | - return *found; | |
65 | + return found; | |
58 | 66 | } |
59 | 67 | |
60 | 68 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -39,10 +39,15 @@ comp(const void * _a, const void * _b) |
39 | 39 | } |
40 | 40 | |
41 | 41 | HttpHeader |
42 | -httpHeaderGet(const HttpHeader * root, const char * name) | |
42 | +httpHeaderGet(const HttpHeader * root, const char * name, size_t nname) | |
43 | 43 | { |
44 | - struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, {}, 0}; | |
45 | - HttpHeader * found = tfind(&search, (void**)root, comp); | |
44 | + struct c_HttpHeader search = { | |
45 | + sdbm((const unsigned char*)name, nname), | |
46 | + NULL, | |
47 | + {}, | |
48 | + 0}; | |
49 | + | |
50 | + HttpHeader * found = tfind(&search, (void**)root, comp); | |
46 | 51 | |
47 | 52 | return (NULL != found)? *found : NULL; |
48 | 53 | } | ... | ... |
... | ... | @@ -28,12 +28,12 @@ |
28 | 28 | size_t |
29 | 29 | httpHeaderSizeGet(HttpHeader header) |
30 | 30 | { |
31 | - size_t nsize = strlen(header->name) + 2; | |
32 | - size_t size = header->nvalue * nsize; | |
31 | + size_t nsize = header->nname + 2; | |
32 | + size_t size = header->cvalue * nsize; | |
33 | 33 | int i; |
34 | 34 | |
35 | - for (i=0; i<header->nvalue; i++) { | |
36 | - size += strlen(header->value[i]) + 2; | |
35 | + for (i=0; i<header->cvalue; i++) { | |
36 | + size += (header->nvalue)[i] + 2; | |
37 | 37 | } |
38 | 38 | |
39 | 39 | return size; | ... | ... |
... | ... | @@ -31,15 +31,15 @@ httpHeaderToString(HttpHeader header, char * string) |
31 | 31 | size_t size = httpHeaderSizeGet(header); |
32 | 32 | int i; |
33 | 33 | |
34 | - for (i=0; i<header->nvalue; i++) { | |
35 | - strcpy(string, header->name); | |
36 | - string += strlen(string); | |
34 | + for (i=0; i<header->cvalue; i++) { | |
35 | + memcpy(string, header->name, header->nname); | |
36 | + string += header->nname; | |
37 | 37 | |
38 | 38 | *string++ = ':'; |
39 | 39 | *string++ = ' '; |
40 | 40 | |
41 | - strcpy(string, header->value[i]); | |
42 | - string += strlen(string); | |
41 | + memcpy(string, header->value[i], header->nvalue[i]); | |
42 | + string += header->nvalue[i]; | |
43 | 43 | |
44 | 44 | *string++ = '\r'; |
45 | 45 | *string++ = '\n'; | ... | ... |
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | */ |
22 | 22 | |
23 | 23 | #include <string.h> |
24 | +#include <sys/types.h> | |
24 | 25 | #include <ctype.h> |
25 | 26 | |
26 | 27 | #include "http/message.h" |
... | ... | @@ -32,20 +33,30 @@ char |
32 | 33 | httpMessageHasKeepAlive(HttpMessage message) |
33 | 34 | { |
34 | 35 | HttpHeader header; |
35 | - char * con; | |
36 | + size_t size; | |
37 | + char * value; | |
38 | + char * keep_alive = "keep-alive"; | |
36 | 39 | |
37 | - header = httpHeaderGet(&(message->header), "connection"); | |
40 | + header = httpHeaderGet( | |
41 | + &(message->header), | |
42 | + "connection", | |
43 | + sizeof("connection")-1); | |
38 | 44 | |
39 | 45 | if (NULL == header) { |
40 | 46 | return 0; |
41 | 47 | } |
42 | 48 | |
43 | - con = (header->value)[0]; | |
44 | - for (; 0 != *con; con++) { | |
45 | - *con = tolower(*con); | |
49 | + if ((sizeof("keep-alive")-1) != (header->nvalue)[0]) { | |
50 | + return 0; | |
46 | 51 | } |
47 | 52 | |
48 | - if (0 == strcmp((header->value)[0], "keep-alive")) { | |
53 | + size = (header->nvalue)[0]; | |
54 | + value = (header->value)[0]; | |
55 | + | |
56 | + for (; 0 < size && tolower(*value) == *keep_alive; | |
57 | + size--, value++, keep_alive++); | |
58 | + | |
59 | + if (0 == size) { | |
49 | 60 | return 1; |
50 | 61 | } |
51 | 62 | ... | ... |
... | ... | @@ -45,7 +45,8 @@ httpRequestParserGetBody(HttpRequestParser this) |
45 | 45 | if (0 == message->nbody) { |
46 | 46 | HttpHeader clen = httpHeaderGet( |
47 | 47 | &(message->header), |
48 | - "Content-Length"); | |
48 | + "Content-Length", | |
49 | + sizeof("Content-Length")-1); | |
49 | 50 | |
50 | 51 | if (NULL == clen) { |
51 | 52 | this->state = HTTP_REQUEST_DONE; | ... | ... |
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | */ |
22 | 22 | |
23 | 23 | #include <string.h> |
24 | +#include <sys/types.h> | |
24 | 25 | |
25 | 26 | #include "class.h" |
26 | 27 | #include "interface/class.h" |
... | ... | @@ -30,28 +31,20 @@ |
30 | 31 | #include "ringbuffer.h" |
31 | 32 | |
32 | 33 | void |
33 | -httpRequestParserGetHeader(HttpMessage message, char * line) | |
34 | +httpRequestParserGetHeader( | |
35 | + HttpMessage message, | |
36 | + const char * line, | |
37 | + const char * line_end) | |
34 | 38 | { |
35 | - HttpMessage message = (HttpMessage)this->cur_request; | |
36 | - char * value; | |
37 | - char * name = this->buffer->buffer + this->buffer->bstart; | |
38 | - size_t len = cr - name; | |
39 | + char * name = line; | |
40 | + char * value = strchr(line, ':'); | |
41 | + size_t nname = (value++) - name; | |
39 | 42 | |
40 | - value = memchr( | |
41 | - this->buffer->buffer + this->buffer->bstart, | |
42 | - ':', len); | |
43 | + for (; *value == ' ' && *value != 0; value++); | |
43 | 44 | |
44 | - if (NULL == value) { | |
45 | - return -1; | |
46 | - } | |
47 | - | |
48 | - *cr = 0; | |
49 | - *(value++) = 0; | |
50 | - while(' ' == *value) value++; | |
51 | - | |
52 | - httpHeaderAdd(&(message->header), new(HttpHeader, name, value)); | |
53 | - | |
54 | - httpHeaderAdd(&(message->header), new(HttpHeader, name, value)); | |
45 | + httpHeaderAdd( | |
46 | + &(message->header), | |
47 | + new(HttpHeader, name, nname, value, line_end-value)); | |
55 | 48 | } |
56 | 49 | |
57 | 50 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -60,8 +60,9 @@ char * method[N_METHODS] = { |
60 | 60 | ssize_t |
61 | 61 | httpRequestParserGetRequestLine(HttpRequestParser this, char * cr) |
62 | 62 | { |
63 | - char * method, * uri, * version; | |
63 | + char * method, * uri, * version; | |
64 | 64 | HttpMessage message = (HttpMessage)request; |
65 | + int mlen, ulen, vlen; | |
65 | 66 | |
66 | 67 | method = line; |
67 | 68 | uri = strchr(line, ' '); |
... | ... | @@ -69,23 +70,25 @@ httpRequestParserGetRequestLine(HttpRequestParser this, char * cr) |
69 | 70 | if (NULL == uri) |
70 | 71 | return; |
71 | 72 | |
72 | - *uri++ = 0; | |
73 | + mlen = uri - method; | |
73 | 74 | for (; *uri == ' ' && *uri != 0; uri++); |
74 | 75 | |
75 | - version = strchr(uri, ' '); | |
76 | + version = strchr(uri, ' '); | |
76 | 77 | |
77 | 78 | if (NULL == version) |
78 | 79 | return; |
79 | 80 | |
80 | - *version++ = 0; | |
81 | + ulen = version - uri; | |
81 | 82 | for (; *version == ' ' && *version != 0; version++); |
82 | 83 | |
83 | - request->method = malloc(strlen(method) + 1); | |
84 | - strcpy(request->method, method); | |
85 | - request->uri = malloc(strlen(uri) + 1); | |
86 | - strcpy(request->uri, uri); | |
87 | - message->version = malloc(strlen(version) + 1); | |
88 | - strcpy(message->version, version); | |
84 | + vlen = strlen(version); | |
85 | + | |
86 | + request->method = calloc(1, mlen + 1); | |
87 | + memcpy(request->method, method, mlen); | |
88 | + request->uri = calloc(1, ulen + 1); | |
89 | + memcpy(request->uri, uri, ulen); | |
90 | + message->version = calloc(1, vlen + 1); | |
91 | + memcpy(message->version, version, vlen); | |
89 | 92 | } |
90 | 93 | |
91 | 94 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -34,6 +34,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
34 | 34 | int cont = 1; |
35 | 35 | ssize_t read; |
36 | 36 | char * line; |
37 | + char * line_end; | |
37 | 38 | |
38 | 39 | if (cbufIsLocked(this->buffer)) { |
39 | 40 | if (FALSE == this->ourLock) |
... | ... | @@ -71,7 +72,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
71 | 72 | break; |
72 | 73 | |
73 | 74 | case HTTP_REQUEST_START: |
74 | - if (NULL == (line = cbufGetLine(this->buffer))) { | |
75 | + if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { | |
75 | 76 | if (! cbufIsEmpty(this->buffer)) { |
76 | 77 | this->isize = this->buffer->bused; |
77 | 78 | this->incomplete = malloc(this->isize); |
... | ... | @@ -101,7 +102,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
101 | 102 | break; |
102 | 103 | |
103 | 104 | case HTTP_REQUEST_REQUEST_LINE_DONE: |
104 | - if (NULL == (line = cbufGetLine(this->buffer))) { | |
105 | + if (NULL == (line = cbufGetLine(this->buffer, &line_end))) { | |
105 | 106 | if (! cbufIsEmpty(this->buffer)) { |
106 | 107 | this->isize = this->buffer->bused; |
107 | 108 | this->incomplete = malloc(this->isize); |
... | ... | @@ -126,15 +127,7 @@ httpRequestParserParse(HttpRequestParser this, int fd) |
126 | 127 | break; |
127 | 128 | } |
128 | 129 | |
129 | - httpRequestParserGetHeader(this, line_end); | |
130 | - | |
131 | - len = line_end - this->buffer->buffer - this->buffer->bstart + 2; | |
132 | - this->buffer->bstart += len; | |
133 | - if (this->buffer->bstart >= this->buffer->bsize) { | |
134 | - this->buffer->bstart -= this->buffer->bsize; | |
135 | - } | |
136 | - this->buffer->bused -= len; | |
137 | - | |
130 | + httpRequestParserGetHeader(this->cur_request, line, line_end); | |
138 | 131 | break; |
139 | 132 | |
140 | 133 | case HTTP_REQUEST_HEADERS_DONE: | ... | ... |
... | ... | @@ -20,6 +20,8 @@ |
20 | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | 21 | */ |
22 | 22 | |
23 | +#include <sys/types.h> | |
24 | + | |
23 | 25 | #include "class.h" |
24 | 26 | #include "interface/class.h" |
25 | 27 | |
... | ... | @@ -29,7 +31,10 @@ |
29 | 31 | |
30 | 32 | |
31 | 33 | HttpResponse |
32 | -httpResponse304(const char * mime, const char * etag, const char * mtime) | |
34 | +httpResponse304( | |
35 | + const char * mime, size_t nmime, | |
36 | + const char * etag, size_t netag, | |
37 | + const char * mtime, size_t nmtime) | |
33 | 38 | { |
34 | 39 | HttpResponse response; |
35 | 40 | HttpMessage message; |
... | ... | @@ -42,11 +47,23 @@ httpResponse304(const char * mime, const char * etag, const char * mtime) |
42 | 47 | message->body = NULL; |
43 | 48 | |
44 | 49 | httpHeaderAdd(&(message->header), |
45 | - new(HttpHeader, "Content-Type", mime)); | |
50 | + new(HttpHeader, | |
51 | + "Content-Type", | |
52 | + sizeof("Content-Type")-1, | |
53 | + mime, | |
54 | + nmime)); | |
46 | 55 | httpHeaderAdd(&(message->header), |
47 | - new(HttpHeader, "ETag", etag)); | |
56 | + new(HttpHeader, | |
57 | + "ETag", | |
58 | + sizeof("ETag")-1, | |
59 | + etag, | |
60 | + netag)); | |
48 | 61 | httpHeaderAdd(&(message->header), |
49 | - new(HttpHeader, "Last-Modified", mtime)); | |
62 | + new(HttpHeader, | |
63 | + "Last-Modified", | |
64 | + sizeof("Last-Modified")-1, | |
65 | + mtime, | |
66 | + nmtime)); | |
50 | 67 | |
51 | 68 | return response; |
52 | 69 | } | ... | ... |
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #include <stdlib.h> |
24 | 24 | #include <string.h> |
25 | 25 | #include <stdio.h> |
26 | +#include <sys/types.h> | |
26 | 27 | |
27 | 28 | #include "class.h" |
28 | 29 | #include "interface/class.h" |
... | ... | @@ -47,21 +48,31 @@ httpResponse404() |
47 | 48 | char buffer[200]; |
48 | 49 | HttpResponse response; |
49 | 50 | HttpMessage message; |
51 | + size_t nbuf; | |
50 | 52 | |
51 | 53 | response = new(HttpResponse, "HTTP/1.1", 404, "Not Found"); |
52 | 54 | message = (HttpMessage)response; |
53 | 55 | |
54 | 56 | httpHeaderAdd(&(message->header), |
55 | - new(HttpHeader, "Content-Type", "text/html")); | |
57 | + new(HttpHeader, | |
58 | + "Content-Type", | |
59 | + sizeof("Content-Type")-1, | |
60 | + "text/html", | |
61 | + sizeof("text/html")-1)); | |
56 | 62 | |
57 | 63 | message->type = HTTP_MESSAGE_BUFFERED; |
58 | 64 | message->nbody = sizeof(RESP_DATA) - 1; |
59 | 65 | message->body = calloc(1, sizeof(RESP_DATA)); |
60 | - strcpy(message->body, RESP_DATA); | |
66 | + memcpy(message->body, RESP_DATA, sizeof(RESP_DATA)); | |
67 | + | |
68 | + nbuf = sprintf(buffer, "%d", message->nbody); | |
61 | 69 | |
62 | - sprintf(buffer, "%d", message->nbody); | |
63 | 70 | httpHeaderAdd(&(message->header), |
64 | - new(HttpHeader, "Content-Length", buffer)); | |
71 | + new(HttpHeader, | |
72 | + "Content-Length", | |
73 | + sizeof("Content-Length")-1, | |
74 | + buffer, | |
75 | + nbuf)); | |
65 | 76 | |
66 | 77 | return response; |
67 | 78 | } | ... | ... |
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | #include <sys/stat.h> |
25 | 25 | #include <fcntl.h> |
26 | 26 | #include <string.h> |
27 | +#include <sys/types.h> | |
27 | 28 | |
28 | 29 | #include "class.h" |
29 | 30 | #include "interface/class.h" |
... | ... | @@ -34,12 +35,20 @@ |
34 | 35 | |
35 | 36 | |
36 | 37 | HttpResponse |
37 | -httpResponseAsset(const char * fname, const char * mime, const char * match) | |
38 | +httpResponseAsset( | |
39 | + const char * fname, | |
40 | + const char * mime, | |
41 | + size_t nmime, | |
42 | + const char * match, | |
43 | + size_t nmatch) | |
38 | 44 | { |
39 | 45 | struct tm * tmp; |
40 | 46 | char etag[200]; |
47 | + size_t netag; | |
41 | 48 | char mtime[200]; |
49 | + size_t nmtime; | |
42 | 50 | char clen[200]; |
51 | + size_t nclen; | |
43 | 52 | struct stat st; |
44 | 53 | HttpResponse response; |
45 | 54 | HttpMessage message; |
... | ... | @@ -48,12 +57,12 @@ httpResponseAsset(const char * fname, const char * mime, const char * match) |
48 | 57 | handle = open(fname, O_RDONLY); |
49 | 58 | fstat(handle, &st); |
50 | 59 | |
51 | - tmp = localtime(&(st.st_mtime)); | |
52 | - strftime(etag, sizeof(etag), "%s", tmp); | |
53 | - strftime(mtime, sizeof(mtime), "%a, %d %b %Y %T %Z", tmp); | |
60 | + tmp = localtime(&(st.st_mtime)); | |
61 | + netag = strftime(etag, sizeof(etag), "%s", tmp); | |
62 | + nmtime = strftime(mtime, sizeof(mtime), "%a, %d %b %Y %T %Z", tmp); | |
54 | 63 | |
55 | - if (0 == strcmp(etag, match)) { | |
56 | - return httpResponse304(mime, etag, mtime); | |
64 | + if (netag == nmatch && 0 == memcmp(etag, match, netag)) { | |
65 | + return httpResponse304(mime, nmime, etag, netag, mtime, nmime); | |
57 | 66 | } |
58 | 67 | |
59 | 68 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
... | ... | @@ -63,16 +72,32 @@ httpResponseAsset(const char * fname, const char * mime, const char * match) |
63 | 72 | message->handle = handle; |
64 | 73 | message->nbody = st.st_size; |
65 | 74 | |
66 | - sprintf(clen, "%d", message->nbody); | |
75 | + nclen = sprintf(clen, "%d", message->nbody); | |
67 | 76 | |
68 | 77 | httpHeaderAdd(&(message->header), |
69 | - new(HttpHeader, "Content-Type", mime)); | |
78 | + new(HttpHeader, | |
79 | + "Content-Type", | |
80 | + sizeof("Content-Type")-1, | |
81 | + mime, | |
82 | + nmime)); | |
70 | 83 | httpHeaderAdd(&(message->header), |
71 | - new(HttpHeader, "Content-Length", clen)); | |
84 | + new(HttpHeader, | |
85 | + "Content-Length", | |
86 | + sizeof("Content-Length")-1, | |
87 | + clen, | |
88 | + nclen)); | |
72 | 89 | httpHeaderAdd(&(message->header), |
73 | - new(HttpHeader, "ETag", etag)); | |
90 | + new(HttpHeader, | |
91 | + "ETag", | |
92 | + sizeof("ETag")-1, | |
93 | + etag, | |
94 | + netag)); | |
74 | 95 | httpHeaderAdd(&(message->header), |
75 | - new(HttpHeader, "Last-Modified", mtime)); | |
96 | + new(HttpHeader, | |
97 | + "Last-Modified", | |
98 | + sizeof("Last-Modified")-1, | |
99 | + mtime, | |
100 | + nmtime)); | |
76 | 101 | |
77 | 102 | return response; |
78 | 103 | } | ... | ... |
... | ... | @@ -23,6 +23,8 @@ |
23 | 23 | #include <stdlib.h> |
24 | 24 | #include <string.h> |
25 | 25 | #include <stdio.h> |
26 | +#include <time.h> | |
27 | +#include <sys/types.h> | |
26 | 28 | |
27 | 29 | #include "class.h" |
28 | 30 | #include "interface/class.h" |
... | ... | @@ -62,25 +64,35 @@ httpResponseMe(int value) |
62 | 64 | char buffer[200]; |
63 | 65 | HttpResponse response; |
64 | 66 | HttpMessage message; |
67 | + size_t nbuf; | |
65 | 68 | |
66 | 69 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
67 | 70 | message = (HttpMessage)response; |
68 | 71 | |
69 | 72 | httpHeaderAdd(&(message->header), |
70 | - new(HttpHeader, "Content-Type", "text/html")); | |
71 | - httpHeaderAdd(&(message->header), | |
73 | + new(HttpHeader, | |
74 | + "Content-Type", | |
75 | + sizeof("Content-Type")-1, | |
76 | + "text/html", | |
77 | + sizeof("text/html")-1)); | |
78 | +/* httpHeaderAdd(&(message->header), | |
72 | 79 | new(HttpHeader, "Set-Cookie", "name=\"Georg Hopp\"")); |
73 | 80 | httpHeaderAdd(&(message->header), |
74 | - new(HttpHeader, "Set-Cookie", "profession=\"coder\"")); | |
81 | + new(HttpHeader, "Set-Cookie", "profession=\"coder\""));*/ | |
75 | 82 | |
76 | 83 | message->type = HTTP_MESSAGE_BUFFERED; |
77 | 84 | message->nbody = sizeof(RESP_DATA)-1-2; |
78 | 85 | message->body = calloc(1, sizeof(RESP_DATA)-2); |
79 | 86 | sprintf(message->body, RESP_DATA, value); |
80 | 87 | |
81 | - sprintf(buffer, "%d", message->nbody); | |
88 | + nbuf = sprintf(buffer, "%d", message->nbody); | |
89 | + | |
82 | 90 | httpHeaderAdd(&(message->header), |
83 | - new(HttpHeader, "Content-Length", buffer)); | |
91 | + new(HttpHeader, | |
92 | + "Content-Length", | |
93 | + sizeof("Content-Length")-1, | |
94 | + buffer, | |
95 | + nbuf)); | |
84 | 96 | |
85 | 97 | return response; |
86 | 98 | } | ... | ... |
1 | 1 | #include <time.h> |
2 | +#include <sys/types.h> | |
2 | 3 | |
3 | 4 | #include "class.h" |
4 | 5 | #include "interface/class.h" |
... | ... | @@ -12,26 +13,43 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) |
12 | 13 | time_t t; |
13 | 14 | struct tm * tmp; |
14 | 15 | char buffer[200]; |
16 | + size_t ndate; | |
15 | 17 | |
16 | 18 | if (httpMessageHasKeepAlive(request)) { |
17 | 19 | httpHeaderAdd( |
18 | 20 | &(response->header), |
19 | - new(HttpHeader, "Connection", "Keep-Alive")); | |
21 | + new(HttpHeader, | |
22 | + "Connection", | |
23 | + sizeof("Connection")-1, | |
24 | + "Keep-Alive", | |
25 | + sizeof("Keep-Alive")-1)); | |
20 | 26 | } |
21 | 27 | else { |
22 | 28 | httpHeaderAdd( |
23 | 29 | &(response->header), |
24 | - new(HttpHeader, "Connection", "Close")); | |
30 | + new(HttpHeader, | |
31 | + "Connection", | |
32 | + sizeof("Connection")-1, | |
33 | + "Close", | |
34 | + sizeof("Close")-1)); | |
25 | 35 | } |
26 | 36 | |
27 | 37 | httpHeaderAdd(&(response->header), |
28 | - new(HttpHeader, "Server", "testserver")); | |
38 | + new(HttpHeader, | |
39 | + "Server", | |
40 | + sizeof("Server")-1, | |
41 | + "testserver", | |
42 | + sizeof("testserver")-1)); | |
29 | 43 | |
30 | - t = time(NULL); | |
31 | - tmp = localtime(&t); | |
32 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
44 | + t = time(NULL); | |
45 | + tmp = localtime(&t); | |
46 | + ndate = strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
33 | 47 | httpHeaderAdd(&(response->header), |
34 | - new(HttpHeader, "Date", buffer)); | |
48 | + new(HttpHeader, | |
49 | + "Date", | |
50 | + sizeof("Date")-1, | |
51 | + buffer, | |
52 | + ndate)); | |
35 | 53 | } |
36 | 54 | |
37 | 55 | // vim: set ts=4 sw=4: | ... | ... |
1 | +#include <sys/types.h> | |
2 | + | |
1 | 3 | #include "http/header.h" |
2 | 4 | #include "http/message.h" |
3 | 5 | #include "http/request.h" |
... | ... | @@ -7,23 +9,29 @@ HttpMessage |
7 | 9 | httpWorkerGetAsset( |
8 | 10 | HttpRequest request, |
9 | 11 | const char * fname, |
10 | - const char * mime) | |
12 | + const char * mime, | |
13 | + size_t nmime) | |
11 | 14 | { |
12 | 15 | char * match; |
16 | + size_t nmatch; | |
13 | 17 | HttpHeader header; |
14 | 18 | |
15 | 19 | header = httpHeaderGet( |
16 | 20 | &(((HttpMessage)request)->header), |
17 | - "If-None-Match"); | |
21 | + "If-None-Match", | |
22 | + sizeof("If-None-Match")-1); | |
18 | 23 | |
19 | 24 | if (NULL == header) { |
20 | - match = ""; | |
25 | + match = ""; | |
26 | + nmatch = 0; | |
21 | 27 | } |
22 | 28 | else { |
23 | - match = (header->value)[0]; | |
29 | + match = (header->value)[0]; | |
30 | + nmatch = (header->nvalue)[0]; | |
24 | 31 | } |
25 | 32 | |
26 | - return (HttpMessage)httpResponseAsset(fname, mime, match); | |
33 | + return (HttpMessage)httpResponseAsset( | |
34 | + fname, mime, nmime, match, nmatch); | |
27 | 35 | } |
28 | 36 | |
29 | 37 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | #include "http/request.h" |
35 | 35 | #include "http/message.h" |
36 | 36 | |
37 | -HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *); | |
37 | +HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); | |
38 | 38 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); |
39 | 39 | |
40 | 40 | ssize_t |
... | ... | @@ -64,14 +64,16 @@ httpWorkerProcess(HttpWorker this, int fd) |
64 | 64 | response = httpWorkerGetAsset( |
65 | 65 | request, |
66 | 66 | "./assets/waldschrat.jpg", |
67 | - "image/jpeg"); | |
67 | + "image/jpeg", | |
68 | + sizeof("image/jpeg")-1); | |
68 | 69 | } |
69 | 70 | |
70 | 71 | if (0 == strcmp("/jquery/", request->uri)) { |
71 | 72 | response = httpWorkerGetAsset( |
72 | 73 | request, |
73 | 74 | "./assets/jquery-1.7.1.min.js", |
74 | - "text/javascript"); | |
75 | + "text/javascript", | |
76 | + sizeof("text/javascript")-1); | |
75 | 77 | } |
76 | 78 | } |
77 | 79 | ... | ... |
1 | 1 | #include <ctype.h> |
2 | +#include <sys/types.h> | |
2 | 3 | |
3 | 4 | #include "utils/hash.h" |
4 | 5 | |
... | ... | @@ -16,13 +17,12 @@ |
16 | 17 | * is one of the algorithms used in berkeley db (see sleepycat) and elsewhere. |
17 | 18 | */ |
18 | 19 | unsigned long |
19 | -sdbm(const unsigned char * str) | |
20 | +sdbm(const unsigned char * str, size_t len) | |
20 | 21 | { |
21 | 22 | unsigned long hash = 0; |
22 | - int c; | |
23 | 23 | |
24 | - while ((c = tolower(*str++))) | |
25 | - hash = c + (hash << 6) + (hash << 16) - hash; | |
24 | + for(; 0 < len; str++, len--) | |
25 | + hash = tolower(*str) + (hash << 6) + (hash << 16) - hash; | |
26 | 26 | |
27 | 27 | return hash; |
28 | 28 | } | ... | ... |
Please
register
or
login
to post a comment