Commit 87b0d50d1d16cda2b63e420f5657826476673715
1 parent
dfcbc494
structural changes for worker/process. @TODO actually i have no idea why this happens.
Showing
33 changed files
with
239 additions
and
291 deletions
1 | +2012-02-22 12:19:40 +0100 Georg Hopp | |
2 | + | |
3 | + * fix memory problems occured with latest changes (HEAD, master) | |
4 | + | |
1 | 5 | 2012-02-22 09:03:40 +0100 Georg Hopp |
2 | 6 | |
3 | - * fixed bug in keep-alive check arised by implementation if #10 (HEAD, master) | |
7 | + * fixed bug in keep-alive check arised by implementation if #10 (origin/master, origin/HEAD) | |
4 | 8 | |
5 | 9 | 2012-02-22 08:51:05 +0100 Georg Hopp |
6 | 10 | |
7 | - * add forgotten jquery assets (origin/master, origin/HEAD) | |
11 | + * add forgotten jquery assets | |
8 | 12 | |
9 | 13 | 2012-02-22 08:48:43 +0100 Georg Hopp |
10 | 14 | ... | ... |
1 | 1 | VERY BIG TODO: |
2 | -- give a contructor a way to fail, so that no object will be created at all | |
3 | - | |
4 | 2 | - right now i will use long polling ajax calls when feedback from to the client |
5 | 3 | is needed. In the long term this should be changed to websockets (ws). But |
6 | 4 | right now ws specification is not final anyway. :) |
5 | + | |
6 | +- handle errors after all system call...especially open, close, etc. | ... | ... |
... | ... | @@ -27,16 +27,18 @@ |
27 | 27 | |
28 | 28 | #include "class.h" |
29 | 29 | |
30 | +#define HTTP_HEADER_VALUE_CHUNK_SIZE 128 | |
31 | + | |
30 | 32 | CLASS(HttpHeader) { |
31 | 33 | unsigned long hash; |
32 | 34 | char * name; |
33 | - char ** value; | |
35 | + char * value[HTTP_HEADER_VALUE_CHUNK_SIZE]; | |
34 | 36 | size_t nvalue; |
35 | 37 | }; |
36 | 38 | |
37 | 39 | HttpHeader httpHeaderParse(char * line); // @INFO: destructive |
38 | 40 | |
39 | -void httpHeaderAdd(const HttpHeader *, HttpHeader); | |
41 | +HttpHeader httpHeaderAdd(const HttpHeader *, HttpHeader); | |
40 | 42 | HttpHeader httpHeaderGet(const HttpHeader *, const char *); |
41 | 43 | size_t httpHeaderSizeGet(HttpHeader); |
42 | 44 | size_t httpHeaderToString(HttpHeader, char *); | ... | ... |
... | ... | @@ -38,11 +38,10 @@ CLASS(HttpResponse) { |
38 | 38 | char * reason; |
39 | 39 | }; |
40 | 40 | |
41 | -HttpResponse httpResponse304(int, const char *); | |
41 | +HttpResponse httpResponse304(const char *, const char *, const char *); | |
42 | 42 | HttpResponse httpResponse404(); |
43 | 43 | HttpResponse httpResponseMe(int); |
44 | -HttpResponse httpResponseImage(int); | |
45 | -HttpResponse httpResponseJquery(int); | |
44 | +HttpResponse httpResponseAsset(const char *, const char *, const char *); | |
46 | 45 | |
47 | 46 | #endif // __HTTP_RESPONSE_H__ |
48 | 47 | ... | ... |
... | ... | @@ -49,7 +49,7 @@ extern void classDelete(void **); |
49 | 49 | extern void * classClone(void *); |
50 | 50 | |
51 | 51 | #define new(class,...) classNew(_##class, ##__VA_ARGS__) |
52 | -#define delete(object) classDelete((void **)(object)) | |
52 | +#define delete(object) classDelete((void **)&(object)) | |
53 | 53 | #define clone(object) classClone((void *)(object)) |
54 | 54 | |
55 | 55 | #endif // __INTERFACE_CLASS_H__ | ... | ... |
... | ... | @@ -23,10 +23,10 @@ REQ = http/request.c http/request/has_valid_method.c |
23 | 23 | RESP = http/response.c \ |
24 | 24 | http/response/304.c \ |
25 | 25 | http/response/404.c \ |
26 | - http/response/image.c \ | |
27 | - http/response/jquery.c \ | |
26 | + http/response/asset.c \ | |
28 | 27 | http/response/me.c |
29 | -WORKER = http/worker.c http/worker/process.c http/worker/write.c | |
28 | +WORKER = http/worker.c http/worker/process.c http/worker/write.c \ | |
29 | + http/worker/get_asset.c http/worker/add_common_header.c | |
30 | 30 | WRITER = http/response/writer.c http/response/writer/write.c |
31 | 31 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
32 | 32 | http/header/size_get.c http/header/to_string.c | ... | ... |
... | ... | @@ -35,18 +35,19 @@ |
35 | 35 | |
36 | 36 | #include "class.h" |
37 | 37 | #include "interface/class.h" |
38 | +#include "utils/memory.h" | |
38 | 39 | |
39 | 40 | #include "cbuf.h" |
40 | 41 | |
41 | 42 | |
42 | -static void dtor(void*); | |
43 | +static void cbufDtor(void*); | |
43 | 44 | |
44 | 45 | static |
45 | 46 | int |
46 | -ctor(void * _this, va_list * params) | |
47 | +cbufCtor(void * _this, va_list * params) | |
47 | 48 | { |
48 | 49 | Cbuf this = _this; |
49 | - char state = 0; | |
50 | + char state = -1; | |
50 | 51 | char * shm_name = va_arg(*params, char*); |
51 | 52 | long psize = sysconf(_SC_PAGESIZE); |
52 | 53 | size_t size; |
... | ... | @@ -64,7 +65,7 @@ ctor(void * _this, va_list * params) |
64 | 65 | size = (0 >= size)? 1 : (0 != size%psize)? (size/psize)+1 : size/psize; |
65 | 66 | this->bsize = psize * size; |
66 | 67 | |
67 | - while (0 == state) { | |
68 | + while (-1 == state) { | |
68 | 69 | shm = shm_open(this->shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRWXU); |
69 | 70 | if (-1 == shm) { |
70 | 71 | break; |
... | ... | @@ -93,7 +94,7 @@ ctor(void * _this, va_list * params) |
93 | 94 | break; |
94 | 95 | } |
95 | 96 | |
96 | - state = 1; | |
97 | + state = 0; | |
97 | 98 | } |
98 | 99 | |
99 | 100 | if (-1 != shm) { |
... | ... | @@ -101,32 +102,25 @@ ctor(void * _this, va_list * params) |
101 | 102 | close(shm); |
102 | 103 | } |
103 | 104 | |
104 | - if (1 != state) { | |
105 | - dtor(this); | |
106 | - } | |
107 | - | |
108 | - return 0; | |
105 | + return state; | |
109 | 106 | } |
110 | 107 | |
111 | 108 | static |
112 | 109 | void |
113 | -dtor(void * _this) | |
110 | +cbufDtor(void * _this) | |
114 | 111 | { |
115 | 112 | Cbuf this = _this; |
116 | 113 | |
117 | - if (NULL != this->shm_name) { | |
118 | - free(this->shm_name); | |
119 | - } | |
114 | + FREE(this->shm_name); | |
120 | 115 | |
121 | 116 | if (NULL != this->data && MAP_FAILED != this->data) { |
122 | 117 | munmap(this->data, this->bsize << 1); |
123 | 118 | } |
124 | 119 | |
125 | - this->shm_name = NULL; | |
126 | - this->data = NULL; | |
120 | + this->data = NULL; | |
127 | 121 | } |
128 | 122 | |
129 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
123 | +INIT_IFACE(Class, cbufCtor, cbufDtor, NULL); | |
130 | 124 | CREATE_CLASS(Cbuf, NULL, IFACE(Class)); |
131 | 125 | |
132 | 126 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | |
34 | 34 | static |
35 | 35 | int |
36 | -ctor(void * _this, va_list * params) { | |
36 | +httpHeaderCtor(void * _this, va_list * params) { | |
37 | 37 | HttpHeader this = _this; |
38 | 38 | char * name; |
39 | 39 | char * value; |
... | ... | @@ -46,29 +46,27 @@ ctor(void * _this, va_list * params) { |
46 | 46 | |
47 | 47 | this->hash = sdbm((unsigned char *)name); |
48 | 48 | |
49 | - this->value = malloc(sizeof(char*) * (++(this->nvalue))); | |
50 | - (this->value)[this->nvalue - 1] = malloc(strlen(value) + 1); | |
51 | - strcpy((this->value)[this->nvalue - 1], value); | |
49 | + (this->value)[this->nvalue] = malloc(strlen(value) + 1); | |
50 | + strcpy((this->value)[this->nvalue++], value); | |
52 | 51 | |
53 | 52 | return 0; |
54 | 53 | } |
55 | 54 | |
56 | 55 | static |
57 | 56 | void |
58 | -dtor(void * _this) | |
57 | +httpHeaderDtor(void * _this) | |
59 | 58 | { |
60 | 59 | HttpHeader this = _this; |
61 | 60 | size_t i; |
62 | 61 | |
63 | - FREE(&(this->name)); | |
62 | + FREE(this->name); | |
64 | 63 | |
65 | 64 | for (i=0; i<this->nvalue; i++) { |
66 | - FREE(&(this->value[i])); | |
65 | + FREE(this->value[i]); | |
67 | 66 | } |
68 | - FREE(&(this->value)); | |
69 | 67 | } |
70 | 68 | |
71 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
69 | +INIT_IFACE(Class, httpHeaderCtor, httpHeaderDtor, NULL); | |
72 | 70 | CREATE_CLASS(HttpHeader, NULL, IFACE(Class)); |
73 | 71 | |
74 | 72 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -40,20 +40,21 @@ comp(const void * _a, const void * _b) |
40 | 40 | return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0; |
41 | 41 | } |
42 | 42 | |
43 | -void | |
43 | +HttpHeader | |
44 | 44 | httpHeaderAdd(const HttpHeader * root, HttpHeader header) |
45 | 45 | { |
46 | 46 | HttpHeader * found = tsearch(header, (void **)root, comp); |
47 | 47 | |
48 | 48 | if (*found != header) { |
49 | - (*found)->value = realloc( | |
50 | - (*found)->value, | |
51 | - sizeof(char*) * (++(*found)->nvalue)); | |
52 | - (*found)->value[(*found)->nvalue - 1] = malloc( | |
53 | - strlen((header->value)[0]) + 1); | |
54 | - strcpy(((*found)->value)[(*found)->nvalue - 1], (header->value)[0]); | |
55 | - delete(&header); | |
49 | + if ((*found)->nvalue >= HTTP_HEADER_VALUE_CHUNK_SIZE) { | |
50 | + return NULL; | |
51 | + } | |
52 | + (*found)->value[(*found)->nvalue++] = (header->value)[0]; | |
53 | + (header->value)[0] = NULL; | |
54 | + delete(header); | |
56 | 55 | } |
56 | + | |
57 | + return *found; | |
57 | 58 | } |
58 | 59 | |
59 | 60 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -28,11 +28,11 @@ |
28 | 28 | size_t |
29 | 29 | httpHeaderSizeGet(HttpHeader header) |
30 | 30 | { |
31 | - size_t size = 0; | |
31 | + size_t nsize = strlen(header->name) + 2; | |
32 | + size_t size = header->nvalue * nsize; | |
32 | 33 | int i; |
33 | 34 | |
34 | 35 | for (i=0; i<header->nvalue; i++) { |
35 | - size += strlen(header->name) + 2; | |
36 | 36 | size += strlen(header->value[i]) + 2; |
37 | 37 | } |
38 | 38 | ... | ... |
... | ... | @@ -42,12 +42,12 @@ inline |
42 | 42 | void |
43 | 43 | tDelete(void * node) |
44 | 44 | { |
45 | - delete(&node); | |
45 | + delete(node); | |
46 | 46 | } |
47 | 47 | |
48 | 48 | static |
49 | 49 | int |
50 | -ctor(void * _this, va_list * params) | |
50 | +httpMessageCtor(void * _this, va_list * params) | |
51 | 51 | { |
52 | 52 | HttpMessage this = _this; |
53 | 53 | char * version = va_arg(* params, char *); |
... | ... | @@ -60,11 +60,11 @@ ctor(void * _this, va_list * params) |
60 | 60 | |
61 | 61 | static |
62 | 62 | void |
63 | -dtor(void * _this) | |
63 | +httpMessageDtor(void * _this) | |
64 | 64 | { |
65 | 65 | HttpMessage this = _this; |
66 | 66 | |
67 | - ffree((void **)&(this->version)); | |
67 | + FREE(this->version); | |
68 | 68 | |
69 | 69 | /** |
70 | 70 | * this is a GNU extension...anyway on most non |
... | ... | @@ -75,7 +75,7 @@ dtor(void * _this) |
75 | 75 | |
76 | 76 | switch (this->type) { |
77 | 77 | case HTTP_MESSAGE_BUFFERED: |
78 | - ffree((void **)&(this->body)); | |
78 | + FREE(this->body); | |
79 | 79 | break; |
80 | 80 | |
81 | 81 | case HTTP_MESSAGE_PIPED: |
... | ... | @@ -87,7 +87,7 @@ dtor(void * _this) |
87 | 87 | } |
88 | 88 | } |
89 | 89 | |
90 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
90 | +INIT_IFACE(Class, httpMessageCtor, httpMessageDtor, NULL); | |
91 | 91 | CREATE_CLASS(HttpMessage, NULL, IFACE(Class)); |
92 | 92 | |
93 | 93 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -29,24 +29,24 @@ |
29 | 29 | |
30 | 30 | static |
31 | 31 | int |
32 | -ctor(void * _this, va_list * params) | |
32 | +messageQueueCtor(void * _this, va_list * params) | |
33 | 33 | { |
34 | 34 | return 0; |
35 | 35 | } |
36 | 36 | |
37 | 37 | static |
38 | 38 | void |
39 | -dtor(void * _this) | |
39 | +messageQueueDtor(void * _this) | |
40 | 40 | { |
41 | 41 | HttpMessageQueue this = _this; |
42 | 42 | int i; |
43 | 43 | |
44 | 44 | for (i=0; i<this->nmsgs; i++) { |
45 | - delete(&(this->msgs)[i]); | |
45 | + delete((this->msgs)[i]); | |
46 | 46 | } |
47 | 47 | } |
48 | 48 | |
49 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
49 | +INIT_IFACE(Class, messageQueueCtor, messageQueueDtor, NULL); | |
50 | 50 | CREATE_CLASS(HttpMessageQueue, NULL, IFACE(Class)); |
51 | 51 | |
52 | 52 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -35,19 +35,23 @@ |
35 | 35 | |
36 | 36 | static |
37 | 37 | int |
38 | -ctor(void * _this, va_list * params) | |
38 | +httpRequestCtor(void * _this, va_list * params) | |
39 | 39 | { |
40 | + /** | |
41 | + * the parent is not called by intention. All infomations | |
42 | + * are read from the request stream. | |
43 | + */ | |
40 | 44 | return 0; |
41 | 45 | } |
42 | 46 | |
43 | 47 | static |
44 | 48 | void |
45 | -dtor(void * _this) | |
49 | +httpRequestDtor(void * _this) | |
46 | 50 | { |
47 | 51 | HttpRequest this = _this; |
48 | 52 | |
49 | - ffree((void **)&(this->uri)); | |
50 | - ffree((void **)&(this->method)); | |
53 | + FREE(this->uri); | |
54 | + FREE(this->method); | |
51 | 55 | |
52 | 56 | PARENTCALL(_this, Class, dtor); |
53 | 57 | } |
... | ... | @@ -88,7 +92,7 @@ toString(void * _this, char * string) |
88 | 92 | return string; |
89 | 93 | } |
90 | 94 | |
91 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
95 | +INIT_IFACE(Class, httpRequestCtor, httpRequestDtor, NULL); | |
92 | 96 | INIT_IFACE(HttpIntro, sizeGet, toString); |
93 | 97 | CREATE_CLASS(HttpRequest, |
94 | 98 | HttpMessage, | ... | ... |
... | ... | @@ -33,10 +33,12 @@ |
33 | 33 | #include "http/request.h" |
34 | 34 | #include "cbuf.h" |
35 | 35 | |
36 | +#include "utils/memory.h" | |
37 | + | |
36 | 38 | |
37 | 39 | static |
38 | 40 | int |
39 | -ctor(void * _this, va_list * params) | |
41 | +requestParserCtor(void * _this, va_list * params) | |
40 | 42 | { |
41 | 43 | HttpRequestParser this = _this; |
42 | 44 | |
... | ... | @@ -48,23 +50,20 @@ ctor(void * _this, va_list * params) |
48 | 50 | |
49 | 51 | static |
50 | 52 | void |
51 | -dtor(void * _this) | |
53 | +requestParserDtor(void * _this) | |
52 | 54 | { |
53 | 55 | HttpRequestParser this = _this; |
54 | 56 | |
55 | - delete(&(this->request_queue)); | |
57 | + delete(this->request_queue); | |
56 | 58 | |
57 | 59 | if (TRUE == this->ourLock) |
58 | 60 | cbufRelease(this->buffer); |
59 | 61 | |
60 | - if (NULL != this->incomplete) | |
61 | - free(this->incomplete); | |
62 | - | |
63 | - if (NULL != this->cur_request) | |
64 | - delete(&(this->cur_request)); | |
62 | + FREE(this->incomplete); | |
63 | + delete(this->cur_request); | |
65 | 64 | } |
66 | 65 | |
67 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
66 | +INIT_IFACE(Class, requestParserCtor, requestParserDtor, NULL); | |
68 | 67 | INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserParse); |
69 | 68 | CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader)); |
70 | 69 | ... | ... |
... | ... | @@ -36,7 +36,7 @@ |
36 | 36 | |
37 | 37 | static |
38 | 38 | int |
39 | -ctor(void * _this, va_list * params) | |
39 | +httpResponseCtor(void * _this, va_list * params) | |
40 | 40 | { |
41 | 41 | HttpResponse this = _this; |
42 | 42 | char * reason; |
... | ... | @@ -54,11 +54,11 @@ ctor(void * _this, va_list * params) |
54 | 54 | |
55 | 55 | static |
56 | 56 | void |
57 | -dtor(void * _this) | |
57 | +httpResponseDtor(void * _this) | |
58 | 58 | { |
59 | 59 | HttpResponse this = _this; |
60 | 60 | |
61 | - ffree((void **)&(this->reason)); | |
61 | + FREE(this->reason); | |
62 | 62 | |
63 | 63 | PARENTCALL(_this, Class, dtor); |
64 | 64 | } |
... | ... | @@ -99,7 +99,7 @@ toString(void * _this, char * string) |
99 | 99 | return string; |
100 | 100 | } |
101 | 101 | |
102 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
102 | +INIT_IFACE(Class, httpResponseCtor, httpResponseDtor, NULL); | |
103 | 103 | INIT_IFACE(HttpIntro, sizeGet, toString); |
104 | 104 | CREATE_CLASS( |
105 | 105 | HttpResponse, | ... | ... |
... | ... | @@ -20,11 +20,6 @@ |
20 | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | 21 | */ |
22 | 22 | |
23 | -#include <stdio.h> | |
24 | -#include <time.h> | |
25 | -#include <sys/stat.h> | |
26 | -#include <fcntl.h> | |
27 | - | |
28 | 23 | #include "class.h" |
29 | 24 | #include "interface/class.h" |
30 | 25 | |
... | ... | @@ -34,44 +29,24 @@ |
34 | 29 | |
35 | 30 | |
36 | 31 | HttpResponse |
37 | -httpResponse304(int handle, const char * content_type) | |
32 | +httpResponse304(const char * mime, const char * etag, const char * mtime) | |
38 | 33 | { |
39 | - time_t t; | |
40 | - struct tm * tmp; | |
41 | - char buffer[200]; | |
42 | - struct stat st; | |
43 | 34 | HttpResponse response; |
44 | 35 | HttpMessage message; |
45 | 36 | |
46 | - fstat(handle, &st); | |
47 | - | |
48 | 37 | response = new(HttpResponse, "HTTP/1.1", 304, "Not Modified"); |
49 | 38 | message = (HttpMessage)response; |
50 | 39 | |
51 | - httpHeaderAdd(&(message->header), | |
52 | - new(HttpHeader, "Content-Type", content_type)); | |
53 | - httpHeaderAdd(&(message->header), | |
54 | - new(HttpHeader, "Server", "testserver")); | |
55 | - | |
56 | 40 | message->type = HTTP_MESSAGE_BUFFERED; |
57 | 41 | message->nbody = 0; |
58 | 42 | message->body = NULL; |
59 | 43 | |
60 | - tmp = localtime(&(st.st_mtime)); | |
61 | - strftime(buffer, sizeof(buffer), "%s", tmp); | |
62 | 44 | httpHeaderAdd(&(message->header), |
63 | - new(HttpHeader, "ETag", buffer)); | |
64 | - | |
65 | - tmp = localtime(&(st.st_mtime)); | |
66 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
45 | + new(HttpHeader, "Content-Type", mime)); | |
67 | 46 | httpHeaderAdd(&(message->header), |
68 | - new(HttpHeader, "Last-Modified", buffer)); | |
69 | - | |
70 | - t = time(NULL); | |
71 | - tmp = localtime(&t); | |
72 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
47 | + new(HttpHeader, "ETag", etag)); | |
73 | 48 | httpHeaderAdd(&(message->header), |
74 | - new(HttpHeader, "Date", buffer)); | |
49 | + new(HttpHeader, "Last-Modified", mtime)); | |
75 | 50 | |
76 | 51 | return response; |
77 | 52 | } | ... | ... |
... | ... | @@ -53,8 +53,6 @@ httpResponse404() |
53 | 53 | |
54 | 54 | httpHeaderAdd(&(message->header), |
55 | 55 | new(HttpHeader, "Content-Type", "text/html")); |
56 | - httpHeaderAdd(&(message->header), | |
57 | - new(HttpHeader, "Server", "testserver")); | |
58 | 56 | |
59 | 57 | message->type = HTTP_MESSAGE_BUFFERED; |
60 | 58 | message->nbody = sizeof(RESP_DATA) - 1; | ... | ... |
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #include <stdio.h> |
24 | 24 | #include <sys/stat.h> |
25 | 25 | #include <fcntl.h> |
26 | +#include <string.h> | |
26 | 27 | |
27 | 28 | #include "class.h" |
28 | 29 | #include "interface/class.h" |
... | ... | @@ -33,41 +34,45 @@ |
33 | 34 | |
34 | 35 | |
35 | 36 | HttpResponse |
36 | -httpResponseImage(int handle) | |
37 | +httpResponseAsset(const char * fname, const char * mime, const char * match) | |
37 | 38 | { |
38 | - char buffer[200]; | |
39 | + struct tm * tmp; | |
40 | + char etag[200]; | |
41 | + char mtime[200]; | |
42 | + char clen[200]; | |
39 | 43 | struct stat st; |
40 | 44 | HttpResponse response; |
41 | 45 | HttpMessage message; |
46 | + int handle; | |
42 | 47 | |
48 | + handle = open(fname, O_RDONLY); | |
43 | 49 | fstat(handle, &st); |
44 | 50 | |
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); | |
54 | + | |
55 | + if (0 == strcmp(etag, match)) { | |
56 | + return httpResponse304(mime, etag, mtime); | |
57 | + } | |
58 | + | |
45 | 59 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
46 | 60 | message = (HttpMessage)response; |
47 | 61 | |
48 | - httpHeaderAdd(&(message->header), | |
49 | - new(HttpHeader, "Content-Type", "image/jpeg")); | |
50 | - httpHeaderAdd(&(message->header), | |
51 | - new(HttpHeader, "Server", "testserver")); | |
52 | - | |
53 | 62 | message->type = HTTP_MESSAGE_PIPED; |
54 | 63 | message->handle = handle; |
55 | 64 | message->nbody = st.st_size; |
56 | 65 | |
57 | - sprintf(buffer, "%d", message->nbody); | |
58 | - httpHeaderAdd(&(message->header), | |
59 | - new(HttpHeader, "Content-Length", buffer)); | |
66 | + sprintf(clen, "%d", message->nbody); | |
60 | 67 | |
61 | - tmp = localtime(&(st.st_mtime)); | |
62 | - strftime(buffer, sizeof(buffer), "%s", tmp); | |
63 | 68 | httpHeaderAdd(&(message->header), |
64 | - new(HttpHeader, "ETag", buffer)); | |
65 | - | |
66 | - t = time(NULL); | |
67 | - tmp = localtime(&t); | |
68 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
69 | + new(HttpHeader, "Content-Type", mime)); | |
70 | + httpHeaderAdd(&(message->header), | |
71 | + new(HttpHeader, "Content-Length", clen)); | |
72 | + httpHeaderAdd(&(message->header), | |
73 | + new(HttpHeader, "ETag", etag)); | |
69 | 74 | httpHeaderAdd(&(message->header), |
70 | - new(HttpHeader, "Date", buffer)); | |
75 | + new(HttpHeader, "Last-Modified", mtime)); | |
71 | 76 | |
72 | 77 | return response; |
73 | 78 | } | ... | ... |
src/http/response/jquery.c
deleted
100644 → 0
1 | -/** | |
2 | - * \file | |
3 | - * | |
4 | - * \author Georg Hopp | |
5 | - * | |
6 | - * \copyright | |
7 | - * Copyright (C) 2012 Georg Hopp | |
8 | - * | |
9 | - * This program is free software: you can redistribute it and/or modify | |
10 | - * it under the terms of the GNU General Public License as published by | |
11 | - * the Free Software Foundation, either version 3 of the License, or | |
12 | - * (at your option) any later version. | |
13 | - * | |
14 | - * This program is distributed in the hope that it will be useful, | |
15 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | - * GNU General Public License for more details. | |
18 | - * | |
19 | - * You should have received a copy of the GNU General Public License | |
20 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21 | - */ | |
22 | - | |
23 | -#include <stdio.h> | |
24 | -#include <time.h> | |
25 | -#include <sys/stat.h> | |
26 | -#include <fcntl.h> | |
27 | - | |
28 | -#include "class.h" | |
29 | -#include "interface/class.h" | |
30 | - | |
31 | -#include "http/response.h" | |
32 | -#include "http/message.h" | |
33 | -#include "http/header.h" | |
34 | - | |
35 | - | |
36 | -HttpResponse | |
37 | -httpResponseJquery(int handle) | |
38 | -{ | |
39 | - time_t t; | |
40 | - struct tm * tmp; | |
41 | - char buffer[200]; | |
42 | - struct stat st; | |
43 | - HttpResponse response; | |
44 | - HttpMessage message; | |
45 | - | |
46 | - fstat(handle, &st); | |
47 | - | |
48 | - response = new(HttpResponse, "HTTP/1.1", 200, "OK"); | |
49 | - message = (HttpMessage)response; | |
50 | - | |
51 | - httpHeaderAdd(&(message->header), | |
52 | - new(HttpHeader, "Content-Type", "text/javascript")); | |
53 | - httpHeaderAdd(&(message->header), | |
54 | - new(HttpHeader, "Server", "testserver")); | |
55 | - | |
56 | - message->type = HTTP_MESSAGE_PIPED; | |
57 | - message->handle = handle; | |
58 | - message->nbody = st.st_size; | |
59 | - | |
60 | - sprintf(buffer, "%d", message->nbody); | |
61 | - httpHeaderAdd(&(message->header), | |
62 | - new(HttpHeader, "Content-Length", buffer)); | |
63 | - | |
64 | - tmp = localtime(&(st.st_mtime)); | |
65 | - strftime(buffer, sizeof(buffer), "%s", tmp); | |
66 | - httpHeaderAdd(&(message->header), | |
67 | - new(HttpHeader, "ETag", buffer)); | |
68 | - | |
69 | - t = time(NULL); | |
70 | - tmp = localtime(&t); | |
71 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
72 | - httpHeaderAdd(&(message->header), | |
73 | - new(HttpHeader, "Date", buffer)); | |
74 | - | |
75 | - return response; | |
76 | -} | |
77 | - | |
78 | -// vim: set ts=4 sw=4: |
... | ... | @@ -69,8 +69,6 @@ httpResponseMe(int value) |
69 | 69 | httpHeaderAdd(&(message->header), |
70 | 70 | new(HttpHeader, "Content-Type", "text/html")); |
71 | 71 | httpHeaderAdd(&(message->header), |
72 | - new(HttpHeader, "Server", "testserver")); | |
73 | - httpHeaderAdd(&(message->header), | |
74 | 72 | new(HttpHeader, "Set-Cookie", "name=\"Georg Hopp\"")); |
75 | 73 | httpHeaderAdd(&(message->header), |
76 | 74 | new(HttpHeader, "Set-Cookie", "profession=\"coder\"")); | ... | ... |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | |
32 | 32 | static |
33 | 33 | int |
34 | -ctor(void * _this, va_list * params) | |
34 | +responseWriterCtor(void * _this, va_list * params) | |
35 | 35 | { |
36 | 36 | HttpResponseWriter this = _this; |
37 | 37 | |
... | ... | @@ -43,20 +43,20 @@ ctor(void * _this, va_list * params) |
43 | 43 | |
44 | 44 | static |
45 | 45 | void |
46 | -dtor(void * _this) | |
46 | +responseWriterDtor(void * _this) | |
47 | 47 | { |
48 | 48 | HttpResponseWriter this = _this; |
49 | 49 | |
50 | - delete(&(this->response_queue)); | |
50 | + delete(this->response_queue); | |
51 | 51 | |
52 | 52 | if (TRUE == this->ourLock) |
53 | 53 | cbufRelease(this->buffer); |
54 | 54 | |
55 | 55 | if (NULL != this->cur_response) |
56 | - delete(&(this->cur_response)); | |
56 | + delete(this->cur_response); | |
57 | 57 | } |
58 | 58 | |
59 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
59 | +INIT_IFACE(Class, responseWriterCtor, responseWriterDtor, NULL); | |
60 | 60 | INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpResponseWriterWrite); |
61 | 61 | CREATE_CLASS(HttpResponseWriter, NULL, IFACE(Class), IFACE(StreamWriter)); |
62 | 62 | ... | ... |
... | ... | @@ -143,13 +143,13 @@ httpResponseWriterWrite(HttpResponseWriter this, int fd) |
143 | 143 | */ |
144 | 144 | cbufRelease(this->buffer); |
145 | 145 | this->ourLock = FALSE; |
146 | - delete(&this->cur_response); | |
146 | + delete(this->cur_response); | |
147 | 147 | return -1; |
148 | 148 | } |
149 | 149 | |
150 | 150 | cbufRelease(this->buffer); |
151 | 151 | this->ourLock = FALSE; |
152 | - delete(&this->cur_response); | |
152 | + delete(this->cur_response); | |
153 | 153 | |
154 | 154 | break; |
155 | 155 | } | ... | ... |
... | ... | @@ -13,10 +13,11 @@ |
13 | 13 | #include "interface/stream_reader.h" |
14 | 14 | #include "interface/stream_writer.h" |
15 | 15 | |
16 | -#define SHMN "/worker_" | |
16 | +#include "utils/memory.h" | |
17 | + | |
17 | 18 | static |
18 | 19 | int |
19 | -ctor(void * _this, va_list * params) | |
20 | +httpWorkerCtor(void * _this, va_list * params) | |
20 | 21 | { |
21 | 22 | HttpWorker this = _this; |
22 | 23 | char * id = va_arg(*params, char *); |
... | ... | @@ -41,17 +42,17 @@ ctor(void * _this, va_list * params) |
41 | 42 | |
42 | 43 | static |
43 | 44 | void |
44 | -dtor(void * _this) | |
45 | +httpWorkerDtor(void * _this) | |
45 | 46 | { |
46 | 47 | HttpWorker this = _this; |
47 | 48 | |
48 | - if (NULL != this->id) free(this->id); | |
49 | + FREE(this->id); | |
49 | 50 | |
50 | - delete(&(this->parser)); | |
51 | - delete(&(this->writer)); | |
51 | + delete(this->parser); | |
52 | + delete(this->writer); | |
52 | 53 | |
53 | - if (NULL != this->pbuf) delete(&(this->pbuf)); | |
54 | - if (NULL != this->wbuf) delete(&(this->wbuf)); | |
54 | + if (NULL != this->pbuf) delete(this->pbuf); | |
55 | + if (NULL != this->wbuf) delete(this->wbuf); | |
55 | 56 | } |
56 | 57 | |
57 | 58 | static |
... | ... | @@ -70,7 +71,7 @@ _clone(void * _this, void * _base) |
70 | 71 | this->writer = new(HttpResponseWriter, base->wbuf); |
71 | 72 | } |
72 | 73 | |
73 | -INIT_IFACE(Class, ctor, dtor, _clone); | |
74 | +INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, _clone); | |
74 | 75 | INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpWorkerProcess); |
75 | 76 | INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpWorkerWrite); |
76 | 77 | CREATE_CLASS( | ... | ... |
src/http/worker/add_common_header.c
0 → 100644
1 | +#include <time.h> | |
2 | + | |
3 | +#include "class.h" | |
4 | +#include "interface/class.h" | |
5 | + | |
6 | +#include "http/message.h" | |
7 | +#include "http/response.h" | |
8 | + | |
9 | +void | |
10 | +httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) | |
11 | +{ | |
12 | + time_t t; | |
13 | + struct tm * tmp; | |
14 | + char buffer[200]; | |
15 | + | |
16 | + if (httpMessageHasKeepAlive(request)) { | |
17 | + httpHeaderAdd( | |
18 | + &(response->header), | |
19 | + new(HttpHeader, "Connection", "Keep-Alive")); | |
20 | + } | |
21 | + else { | |
22 | + httpHeaderAdd( | |
23 | + &(response->header), | |
24 | + new(HttpHeader, "Connection", "Close")); | |
25 | + } | |
26 | + | |
27 | + httpHeaderAdd(&(response->header), | |
28 | + new(HttpHeader, "Server", "testserver")); | |
29 | + | |
30 | + t = time(NULL); | |
31 | + tmp = localtime(&t); | |
32 | + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | |
33 | + httpHeaderAdd(&(response->header), | |
34 | + new(HttpHeader, "Date", buffer)); | |
35 | +} | |
36 | + | |
37 | +// vim: set ts=4 sw=4: | ... | ... |
src/http/worker/get_asset.c
0 → 100644
1 | +#include "http/header.h" | |
2 | +#include "http/message.h" | |
3 | +#include "http/request.h" | |
4 | +#include "http/response.h" | |
5 | + | |
6 | +HttpMessage | |
7 | +httpWorkerGetAsset( | |
8 | + HttpRequest request, | |
9 | + const char * fname, | |
10 | + const char * mime) | |
11 | +{ | |
12 | + char * match; | |
13 | + HttpHeader header; | |
14 | + | |
15 | + header = httpHeaderGet( | |
16 | + &(((HttpMessage)request)->header), | |
17 | + "If-None-Match"); | |
18 | + | |
19 | + if (NULL == header) { | |
20 | + match = ""; | |
21 | + } | |
22 | + else { | |
23 | + match = (header->value)[0]; | |
24 | + } | |
25 | + | |
26 | + return (HttpMessage)httpResponseAsset(fname, mime, match); | |
27 | +} | |
28 | + | |
29 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -21,18 +21,22 @@ |
21 | 21 | */ |
22 | 22 | |
23 | 23 | #include <sys/types.h> |
24 | -#include <sys/stat.h> | |
25 | -#include <fcntl.h> | |
26 | 24 | |
27 | 25 | #include "class.h" |
28 | 26 | #include "interface/class.h" |
29 | 27 | |
30 | 28 | #include "http/worker.h" |
29 | +#include "http/message.h" | |
30 | +#include "http/request.h" | |
31 | +#include "http/message/queue.h" | |
31 | 32 | #include "http/request/parser.h" |
32 | 33 | #include "http/header.h" |
33 | 34 | #include "http/request.h" |
34 | 35 | #include "http/message.h" |
35 | 36 | |
37 | +HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *); | |
38 | +void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); | |
39 | + | |
36 | 40 | ssize_t |
37 | 41 | httpWorkerProcess(HttpWorker this, int fd) |
38 | 42 | { |
... | ... | @@ -47,57 +51,35 @@ httpWorkerProcess(HttpWorker this, int fd) |
47 | 51 | HttpMessageQueue respq = this->writer->response_queue; |
48 | 52 | |
49 | 53 | for (i=0; i<reqq->nmsgs; i++) { |
50 | - /** | |
51 | - * \todo for now simply remove request and send not found. | |
52 | - * Make this sane. | |
53 | - */ | |
54 | - HttpRequest request = (HttpRequest)(reqq->msgs[i]); | |
55 | - HttpMessage response = NULL; | |
56 | - | |
57 | - if (0 == strcmp("GET", request->method) && | |
58 | - 0 == strcmp("/me/", request->uri)) { | |
59 | - response = (HttpMessage)httpResponseMe(*(this->val)); | |
60 | - } | |
61 | - else if (0 == strcmp("GET", request->method) && | |
62 | - 0 == strcmp("/image/", request->uri)) { | |
63 | - int handle = open("./assets/waldschrat.jpg", O_RDONLY); | |
64 | - | |
65 | - if (NULL != httpHeaderGet( | |
66 | - &(((HttpMessage)request)->header), | |
67 | - "If-None-Match")) { | |
68 | - response = (HttpMessage)httpResponse304(handle, "image/jpeg"); | |
69 | - } | |
70 | - else { | |
71 | - response = (HttpMessage)httpResponseImage(handle); | |
54 | + HttpRequest request = (HttpRequest)(reqq->msgs[i]); | |
55 | + HttpMessage response = NULL; | |
56 | + | |
57 | + if (0 == strcmp("GET", request->method)) { | |
58 | + | |
59 | + if (0 == strcmp("/me/", request->uri)) { | |
60 | + response = (HttpMessage)httpResponseMe(*(this->val)); | |
72 | 61 | } |
73 | - } | |
74 | - else if (0 == strcmp("GET", request->method) && | |
75 | - 0 == strcmp("/jquery/", request->uri)) { | |
76 | - int handle = open("./assets/jquery-1.7.1.min.js", O_RDONLY); | |
77 | - | |
78 | - if (NULL != httpHeaderGet( | |
79 | - &(((HttpMessage)request)->header), | |
80 | - "If-None-Match")) { | |
81 | - response = (HttpMessage)httpResponse304(handle, "text/javascript"); | |
62 | + | |
63 | + if (0 == strcmp("/image/", request->uri)) { | |
64 | + response = httpWorkerGetAsset( | |
65 | + request, | |
66 | + "./assets/waldschrat.jpg", | |
67 | + "image/jpeg"); | |
82 | 68 | } |
83 | - else { | |
84 | - response = (HttpMessage)httpResponseJquery(handle); | |
69 | + | |
70 | + if (0 == strcmp("/jquery/", request->uri)) { | |
71 | + response = httpWorkerGetAsset( | |
72 | + request, | |
73 | + "./assets/jquery-1.7.1.min.js", | |
74 | + "text/javascript"); | |
85 | 75 | } |
86 | 76 | } |
87 | - else { | |
77 | + | |
78 | + if (NULL == response) { | |
88 | 79 | response = (HttpMessage)httpResponse404(); |
89 | 80 | } |
90 | 81 | |
91 | - if (httpMessageHasKeepAlive(reqq->msgs[i])) { | |
92 | - httpHeaderAdd( | |
93 | - &(response->header), | |
94 | - new(HttpHeader, "Connection", "Keep-Alive")); | |
95 | - } | |
96 | - else { | |
97 | - httpHeaderAdd( | |
98 | - &(response->header), | |
99 | - new(HttpHeader, "Connection", "Close")); | |
100 | - } | |
82 | + httpWorkerAddCommonHeader((HttpMessage)request, response); | |
101 | 83 | |
102 | 84 | t = time(NULL); |
103 | 85 | tmp = localtime(&t); |
... | ... | @@ -107,7 +89,7 @@ httpWorkerProcess(HttpWorker this, int fd) |
107 | 89 | |
108 | 90 | respq->msgs[(respq->nmsgs)++] = response; |
109 | 91 | response = NULL; |
110 | - delete(&(reqq->msgs[i])); | |
92 | + delete((reqq->msgs)[i]); | |
111 | 93 | } |
112 | 94 | |
113 | 95 | reqq->nmsgs = 0; | ... | ... |
... | ... | @@ -41,7 +41,7 @@ logger_level_str[] = { |
41 | 41 | |
42 | 42 | static |
43 | 43 | int |
44 | -ctor(void * _this, va_list * params) | |
44 | +loggerCtor(void * _this, va_list * params) | |
45 | 45 | { |
46 | 46 | Logger this = _this; |
47 | 47 | this->min_level = va_arg(*params, int); |
... | ... | @@ -49,9 +49,9 @@ ctor(void * _this, va_list * params) |
49 | 49 | return 0; |
50 | 50 | } |
51 | 51 | |
52 | -static void dtor(void * _this) {} | |
52 | +static void loggerDtor(void * _this) {} | |
53 | 53 | |
54 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
54 | +INIT_IFACE(Class, loggerCtor, loggerDtor, NULL); | |
55 | 55 | CREATE_CLASS(Logger, NULL, IFACE(Class)); |
56 | 56 | |
57 | 57 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | |
35 | 35 | static |
36 | 36 | int |
37 | -ctor(void * _this, va_list * params) | |
37 | +serverCtor(void * _this, va_list * params) | |
38 | 38 | { |
39 | 39 | Server this = _this; |
40 | 40 | in_port_t port; |
... | ... | @@ -73,25 +73,25 @@ ctor(void * _this, va_list * params) |
73 | 73 | |
74 | 74 | static |
75 | 75 | void |
76 | -dtor(void * _this) | |
76 | +serverDtor(void * _this) | |
77 | 77 | { |
78 | 78 | Server this = _this; |
79 | 79 | int i; |
80 | 80 | |
81 | 81 | for (i=0; i<this->nfds; i++) { |
82 | 82 | if (this->sock->handle != (this->fds)[i].fd) { |
83 | - delete(&(this->conns[(this->fds)[i].fd]).sock); | |
84 | - delete(&(this->conns[(this->fds)[i].fd]).worker); | |
83 | + delete((this->conns[(this->fds)[i].fd]).sock); | |
84 | + delete((this->conns[(this->fds)[i].fd]).worker); | |
85 | 85 | } |
86 | 86 | } |
87 | 87 | |
88 | - FREE(&(this->fds)); | |
89 | - FREE(&(this->conns)); | |
88 | + FREE(this->fds); | |
89 | + FREE(this->conns); | |
90 | 90 | |
91 | - delete(&this->sock); | |
91 | + delete(this->sock); | |
92 | 92 | } |
93 | 93 | |
94 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
94 | +INIT_IFACE(Class, serverCtor, serverDtor, NULL); | |
95 | 95 | CREATE_CLASS(Server, NULL, IFACE(Class)); |
96 | 96 | |
97 | 97 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -31,8 +31,8 @@ serverCloseConn(Server this, unsigned int i) |
31 | 31 | { |
32 | 32 | int fd = (this->fds)[i].fd; |
33 | 33 | |
34 | - delete(&((this->conns)[fd].sock)); | |
35 | - delete(&((this->conns)[fd].worker)); | |
34 | + delete((this->conns)[fd].sock); | |
35 | + delete((this->conns)[fd].worker); | |
36 | 36 | |
37 | 37 | memset(&(this->fds[i]), 0, sizeof(struct pollfd)); |
38 | 38 | } | ... | ... |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | |
32 | 32 | static |
33 | 33 | int |
34 | -ctor(void * _this, va_list * params) | |
34 | +socketCtor(void * _this, va_list * params) | |
35 | 35 | { |
36 | 36 | Sock this = _this; |
37 | 37 | int reUse = 1; //! \todo make this configurable |
... | ... | @@ -44,7 +44,7 @@ ctor(void * _this, va_list * params) |
44 | 44 | loggerLog(this->log, LOGGER_CRIT, |
45 | 45 | "error opening socket: %s - service terminated", |
46 | 46 | strerror(errno)); |
47 | - return; | |
47 | + return -1; | |
48 | 48 | } |
49 | 49 | |
50 | 50 | //! Make the socket REUSE a TIME_WAIT socket |
... | ... | @@ -55,7 +55,7 @@ ctor(void * _this, va_list * params) |
55 | 55 | |
56 | 56 | static |
57 | 57 | void |
58 | -dtor(void * _this) | |
58 | +socketDtor(void * _this) | |
59 | 59 | { |
60 | 60 | Sock this = _this; |
61 | 61 | |
... | ... | @@ -65,7 +65,7 @@ dtor(void * _this) |
65 | 65 | } |
66 | 66 | } |
67 | 67 | |
68 | -INIT_IFACE(Class, ctor, dtor, NULL); | |
68 | +INIT_IFACE(Class, socketCtor, socketDtor, NULL); | |
69 | 69 | CREATE_CLASS(Sock, NULL, IFACE(Class)); |
70 | 70 | |
71 | 71 | // vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -165,9 +165,9 @@ main() |
165 | 165 | } |
166 | 166 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); |
167 | 167 | |
168 | - if (NULL != server) delete(&server); | |
169 | - if (NULL != worker) delete(&worker); | |
170 | - if (NULL != logger) delete(&logger); | |
168 | + if (NULL != server) delete(server); | |
169 | + if (NULL != worker) delete(worker); | |
170 | + if (NULL != logger) delete(logger); | |
171 | 171 | } |
172 | 172 | |
173 | 173 | break; | ... | ... |
Please
register
or
login
to post a comment