Commit 646d1e1c50ad972e8098c2b23e531d58a043c181
1 parent
784364db
Added a new abstraction: hash. A a lot of things within http are key/value thing…
…s based on stings i created this generic hash class and use it to store the header right now. In future it will also be used to store cookie, get and post vars
Showing
28 changed files
with
323 additions
and
265 deletions
include/hash.h
0 → 100644
1 | +#ifndef __HASH_H__ | |
2 | +#define __HASH_H__ | |
3 | + | |
4 | +#include <sys/types.h> | |
5 | + | |
6 | +#include "class.h" | |
7 | + | |
8 | + | |
9 | +CLASS(Hash) { | |
10 | + void * root; | |
11 | +}; | |
12 | + | |
13 | +void * hashAdd(Hash, void *); | |
14 | +void * hashDelete(Hash, const char *, size_t); | |
15 | +void * hashGet(Hash, const char *, size_t); | |
16 | +void hashEach(Hash, void (*)(const void*)); | |
17 | + | |
18 | +#endif // __HASH_H__ | |
19 | + | |
20 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -41,8 +41,6 @@ CLASS(HttpHeader) { |
41 | 41 | size_t size; //!< full size of this header |
42 | 42 | }; |
43 | 43 | |
44 | -HttpHeader httpHeaderAdd(const HttpHeader *, HttpHeader); | |
45 | -HttpHeader httpHeaderGet(const HttpHeader *, const char *, size_t); | |
46 | 44 | size_t httpHeaderToString(HttpHeader, char *); |
47 | 45 | |
48 | 46 | #endif // __HTTP_HEADER_H__ | ... | ... |
... | ... | @@ -25,7 +25,7 @@ |
25 | 25 | #define __HTTP_MESSAGE__ |
26 | 26 | |
27 | 27 | #include "class.h" |
28 | -#include "http/header.h" | |
28 | +#include "hash.h" | |
29 | 29 | #include "stream.h" |
30 | 30 | |
31 | 31 | typedef enum e_HttpMessageType { |
... | ... | @@ -37,7 +37,7 @@ typedef enum e_HttpMessageType { |
37 | 37 | CLASS(HttpMessage) { |
38 | 38 | char * version; |
39 | 39 | |
40 | - HttpHeader header; | |
40 | + Hash header; | |
41 | 41 | |
42 | 42 | HttpMessageType type; |
43 | 43 | Stream handle; | ... | ... |
include/interface/hashable.h
0 → 100644
1 | +/** | |
2 | + * \file | |
3 | + * The logger interface. | |
4 | + * | |
5 | + * \author Georg Hopp | |
6 | + * | |
7 | + * \copyright | |
8 | + * Copyright (C) 2012 Georg Hopp | |
9 | + * | |
10 | + * This program is free software: you can redistribute it and/or modify | |
11 | + * it under the terms of the GNU General Public License as published by | |
12 | + * the Free Software Foundation, either version 3 of the License, or | |
13 | + * (at your option) any later version. | |
14 | + * | |
15 | + * This program is distributed in the hope that it will be useful, | |
16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | + * GNU General Public License for more details. | |
19 | + * | |
20 | + * You should have received a copy of the GNU General Public License | |
21 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
22 | + */ | |
23 | + | |
24 | +#ifndef __INTERFACE_HASHABLE_H__ | |
25 | +#define __INTERFACE_HASHABLE_H__ | |
26 | + | |
27 | +#include "interface.h" | |
28 | + | |
29 | +typedef unsigned long (* fptr_hashableGetHash)(void *); | |
30 | +typedef void (* fptr_hashableHandleDouble)(void *, void *); | |
31 | + | |
32 | +extern const struct interface i_Hashable; | |
33 | + | |
34 | +struct i_Hashable { | |
35 | + const struct interface * const _; | |
36 | + fptr_hashableGetHash getHash; | |
37 | + fptr_hashableHandleDouble handleDouble; | |
38 | +}; | |
39 | + | |
40 | +extern unsigned long hashableGetHash(void *); | |
41 | +extern void hashableHandleDouble(void *, void *); | |
42 | + | |
43 | +#endif // __INTERFACE_HASHABLE_H__ | |
44 | + | |
45 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -6,6 +6,12 @@ IFACE = interface/class.c interface/stream_reader.c interface/logger.c \ |
6 | 6 | interface/subject.c interface/observer.c interface.c |
7 | 7 | SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c |
8 | 8 | STREAM = stream.c stream/read.c stream/write.c |
9 | +HASH = hash.c \ | |
10 | + hash/add.c \ | |
11 | + hash/get.c \ | |
12 | + hash/delete.c \ | |
13 | + hash/each.c \ | |
14 | + interface/hashable.c | |
9 | 15 | SERVER = server.c server/run.c server/close_conn.c server/poll.c \ |
10 | 16 | server/handle_accept.c server/read.c server/write.c |
11 | 17 | LOGGER = logger.c logger/stderr.c logger/syslog.c |
... | ... | @@ -44,7 +50,7 @@ WORKER = http/worker.c \ |
44 | 50 | http/worker/write.c \ |
45 | 51 | http/worker/get_asset.c \ |
46 | 52 | http/worker/add_common_header.c |
47 | -HEADER = http/header.c http/header/get.c http/header/add.c \ | |
53 | +HEADER = http/header.c \ | |
48 | 54 | http/header/to_string.c |
49 | 55 | SESSION = session.c session/add.c session/get.c session/delete.c |
50 | 56 | UTILS = utils/hash.c \ |
... | ... | @@ -61,6 +67,6 @@ bin_PROGRAMS = webgameserver |
61 | 67 | webgameserver_SOURCES = webgameserver.c \ |
62 | 68 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ |
63 | 69 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ |
64 | - $(UTILS) $(MSGQ) $(SESSION) $(STREAM) | |
70 | + $(UTILS) $(MSGQ) $(SESSION) $(STREAM) $(HASH) | |
65 | 71 | webgameserver_CFLAGS = -Wall -I ../include/ |
66 | 72 | webgameserver_LDFLAGS = -lrt -lssl | ... | ... |
src/hash.c
0 → 100644
1 | +#define _GNU_SOURCE | |
2 | + | |
3 | +#include <search.h> | |
4 | +#include <stdarg.h> | |
5 | + | |
6 | +#include "hash.h" | |
7 | +#include "class.h" | |
8 | +#include "interface/class.h" | |
9 | + | |
10 | +static | |
11 | +int | |
12 | +hashCtor(void * _this, va_list * params) | |
13 | +{ | |
14 | + return 0; | |
15 | +} | |
16 | + | |
17 | +static | |
18 | +inline | |
19 | +void | |
20 | +tDelete(void * node) | |
21 | +{ | |
22 | + delete(node); | |
23 | +} | |
24 | + | |
25 | +static | |
26 | +void | |
27 | +hashDtor(void * _this) | |
28 | +{ | |
29 | + Hash this = _this; | |
30 | + | |
31 | + /** | |
32 | + * this is a GNU extension...anyway on most non | |
33 | + * GNUish systems i would not use tsearch anyway | |
34 | + * as the trees will be unbalanced. | |
35 | + */ | |
36 | + tdestroy(this->root, tDelete); | |
37 | +} | |
38 | + | |
39 | +INIT_IFACE(Class, hashCtor, hashDtor, NULL); | |
40 | +CREATE_CLASS(Hash, NULL, IFACE(Class)); | |
41 | + | |
42 | +// vim: set ts=4 sw=4: | ... | ... |
src/hash/add.c
0 → 100644
1 | +#include <search.h> | |
2 | + | |
3 | +#include "hash.h" | |
4 | +#include "interface/hashable.h" | |
5 | +#include "interface/class.h" | |
6 | + | |
7 | +static | |
8 | +inline | |
9 | +int | |
10 | +hashAddComp(const void * a, const void * b) | |
11 | +{ | |
12 | + return hashableGetHash((void*)b) - hashableGetHash((void*)a); | |
13 | +} | |
14 | + | |
15 | +void * | |
16 | +hashAdd(Hash this, void * operand) | |
17 | +{ | |
18 | + void * found = tsearch(operand, &(this->root), hashAddComp); | |
19 | + | |
20 | + if (NULL == found) { | |
21 | + return NULL; | |
22 | + } | |
23 | + | |
24 | + if (operand != *(void**)found) { | |
25 | + hashableHandleDouble(*(void**)found, operand); | |
26 | + delete(operand); | |
27 | + } | |
28 | + | |
29 | + return *(void**)found; | |
30 | +} | |
31 | + | |
32 | +// vim: set ts=4 sw=4: | ... | ... |
src/hash/delete.c
0 → 100644
1 | +#include <search.h> | |
2 | +#include <sys/types.h> | |
3 | + | |
4 | +#include "hash.h" | |
5 | +#include "interface/hashable.h" | |
6 | +#include "utils/hash.h" | |
7 | + | |
8 | +static | |
9 | +inline | |
10 | +int | |
11 | +hashDeleteComp(const void * a, const void * b) | |
12 | +{ | |
13 | + return hashableGetHash((void*)b) - *(const unsigned long*)a; | |
14 | +} | |
15 | + | |
16 | +void * | |
17 | +hashDelete(Hash this, const char * search, size_t nsearch) | |
18 | +{ | |
19 | + unsigned long hash = sdbm((const unsigned char *)search, nsearch); | |
20 | + void * found = tfind(&hash, &(this->root), hashDeleteComp); | |
21 | + | |
22 | + return (NULL != found)? *(void**)found : NULL; | |
23 | +} | |
24 | + | |
25 | +// vim: set ts=4 sw=4: | ... | ... |
src/hash/each.c
0 → 100644
1 | +#include <search.h> | |
2 | + | |
3 | +#include "hash.h" | |
4 | + | |
5 | +static void (*cb)(void*); | |
6 | + | |
7 | +static | |
8 | +inline | |
9 | +void | |
10 | +walk(const void * node, const VISIT which, const int depth) | |
11 | +{ | |
12 | + if (endorder == which || leaf == which) { | |
13 | + cb(*(void**)node); | |
14 | + } | |
15 | +} | |
16 | + | |
17 | +void | |
18 | +hashEach(Hash this, void (*callback)(const void*)) | |
19 | +{ | |
20 | + cb = callback; | |
21 | + | |
22 | + twalk(this->root, walk); | |
23 | +} | |
24 | + | |
25 | +// vim: set ts=4 sw=4: | ... | ... |
src/hash/get.c
0 → 100644
1 | +#include <search.h> | |
2 | +#include <sys/types.h> | |
3 | + | |
4 | +#include "hash.h" | |
5 | +#include "interface/hashable.h" | |
6 | +#include "utils/hash.h" | |
7 | + | |
8 | +static | |
9 | +inline | |
10 | +int | |
11 | +hashGetComp(const void * a, const void * b) | |
12 | +{ | |
13 | + return hashableGetHash((void*)b) - *(const unsigned long*)a; | |
14 | +} | |
15 | + | |
16 | +void * | |
17 | +hashGet(Hash this, const char * search, size_t nsearch) | |
18 | +{ | |
19 | + unsigned long hash = sdbm((const unsigned char *)search, nsearch); | |
20 | + void * found = tfind(&hash, &(this->root), hashGetComp); | |
21 | + | |
22 | + return (NULL != found)? *(void**)found : NULL; | |
23 | +} | |
24 | + | |
25 | +// vim: set ts=4 sw=4: | ... | ... |
... | ... | @@ -27,6 +27,7 @@ |
27 | 27 | #include "class.h" |
28 | 28 | #include "interface/class.h" |
29 | 29 | #include "http/header.h" |
30 | +#include "interface/hashable.h" | |
30 | 31 | |
31 | 32 | #include "utils/hash.h" |
32 | 33 | #include "utils/memory.h" |
... | ... | @@ -72,7 +73,35 @@ httpHeaderDtor(void * _this) |
72 | 73 | } |
73 | 74 | } |
74 | 75 | |
76 | +static | |
77 | +unsigned long | |
78 | +httpHeaderGetHash(void * _this) | |
79 | +{ | |
80 | + HttpHeader this = _this; | |
81 | + | |
82 | + return this->hash; | |
83 | +} | |
84 | + | |
85 | +static | |
86 | +void | |
87 | +httpHeaderHandleDouble(void * _this, void * _double) | |
88 | +{ | |
89 | + HttpHeader this = _this; | |
90 | + HttpHeader doub = _double; | |
91 | + | |
92 | + if (this->cvalue >= N_VALUES) { | |
93 | + //! \todo do dome error logging...or change to HEAP | |
94 | + return; | |
95 | + } | |
96 | + | |
97 | + (this->nvalue)[this->cvalue] = (doub->nvalue)[0]; | |
98 | + (this->value)[(this->cvalue)++] = (doub->value)[0]; | |
99 | + this->size += doub->size; | |
100 | + (doub->value)[0] = NULL; | |
101 | +} | |
102 | + | |
75 | 103 | INIT_IFACE(Class, httpHeaderCtor, httpHeaderDtor, NULL); |
76 | -CREATE_CLASS(HttpHeader, NULL, IFACE(Class)); | |
104 | +INIT_IFACE(Hashable, httpHeaderGetHash, httpHeaderHandleDouble); | |
105 | +CREATE_CLASS(HttpHeader, NULL, IFACE(Class), IFACE(Hashable)); | |
77 | 106 | |
78 | 107 | // vim: set ts=4 sw=4: | ... | ... |
src/http/header/add.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 <search.h> | |
24 | -#include <stdio.h> | |
25 | -#include <stdlib.h> | |
26 | -#include <string.h> | |
27 | - | |
28 | -#include "class.h" | |
29 | -#include "interface/class.h" | |
30 | -#include "http/header.h" | |
31 | -#include "utils/hash.h" | |
32 | - | |
33 | -static | |
34 | -inline | |
35 | -int | |
36 | -comp(const void * _a, const void * _b) | |
37 | -{ | |
38 | - HttpHeader a = (HttpHeader)_a; | |
39 | - HttpHeader b = (HttpHeader)_b; | |
40 | - return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0; | |
41 | -} | |
42 | - | |
43 | -HttpHeader | |
44 | -httpHeaderAdd(const HttpHeader * root, HttpHeader header) | |
45 | -{ | |
46 | - HttpHeader * _found = tsearch(header, (void **)root, comp); | |
47 | - HttpHeader found; | |
48 | - | |
49 | - if (NULL == _found) { | |
50 | - return NULL; | |
51 | - } | |
52 | - | |
53 | - found = *_found; | |
54 | - | |
55 | - if (found != header) { | |
56 | - if (found->cvalue >= N_VALUES) { | |
57 | - return NULL; | |
58 | - } | |
59 | - (found->nvalue)[found->cvalue] = (header->nvalue)[0]; | |
60 | - (found->value)[(found->cvalue)++] = (header->value)[0]; | |
61 | - found->size += header->size; | |
62 | - (header->value)[0] = NULL; | |
63 | - delete(header); | |
64 | - } | |
65 | - | |
66 | - return found; | |
67 | -} | |
68 | - | |
69 | -// vim: set ts=4 sw=4: |
... | ... | @@ -32,20 +32,12 @@ |
32 | 32 | |
33 | 33 | #include "class.h" |
34 | 34 | #include "interface/class.h" |
35 | - | |
35 | +#include "hash.h" | |
36 | 36 | #include "http/message.h" |
37 | 37 | #include "utils/memory.h" |
38 | 38 | |
39 | 39 | |
40 | 40 | static |
41 | -inline | |
42 | -void | |
43 | -tDelete(void * node) | |
44 | -{ | |
45 | - delete(node); | |
46 | -} | |
47 | - | |
48 | -static | |
49 | 41 | int |
50 | 42 | httpMessageCtor(void * _this, va_list * params) |
51 | 43 | { |
... | ... | @@ -55,6 +47,8 @@ httpMessageCtor(void * _this, va_list * params) |
55 | 47 | this->version = calloc(1, strlen(version)+1); |
56 | 48 | strcpy(this->version, version); |
57 | 49 | |
50 | + this->header = new(Hash); | |
51 | + | |
58 | 52 | return 0; |
59 | 53 | } |
60 | 54 | |
... | ... | @@ -64,15 +58,9 @@ httpMessageDtor(void * _this) |
64 | 58 | { |
65 | 59 | HttpMessage this = _this; |
66 | 60 | |
61 | + delete(this->header); | |
67 | 62 | FREE(this->version); |
68 | 63 | |
69 | - /** | |
70 | - * this is a GNU extension...anyway on most non | |
71 | - * GNUish systems i would not use tsearch anyway | |
72 | - * as the trees will be unbalanced. | |
73 | - */ | |
74 | - tdestroy(this->header, tDelete); | |
75 | - | |
76 | 64 | switch (this->type) { |
77 | 65 | case HTTP_MESSAGE_BUFFERED: |
78 | 66 | FREE(this->body); | ... | ... |
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | #include "utils/memory.h" |
32 | 32 | |
33 | 33 | #include "commons.h" |
34 | +#include "hash.h" | |
34 | 35 | |
35 | 36 | char |
36 | 37 | httpMessageHasKeepAlive(HttpMessage message) |
... | ... | @@ -39,7 +40,7 @@ httpMessageHasKeepAlive(HttpMessage message) |
39 | 40 | size_t size; |
40 | 41 | char * value; |
41 | 42 | |
42 | - header = httpHeaderGet(&(message->header), CSTRA("connection")); | |
43 | + header = hashGet(message->header, CSTRA("connection")); | |
43 | 44 | |
44 | 45 | if (NULL == header) { |
45 | 46 | return 0; | ... | ... |
... | ... | @@ -28,17 +28,16 @@ |
28 | 28 | #include "http/response.h" |
29 | 29 | #include "http/header.h" |
30 | 30 | #include "interface/http_intro.h" |
31 | +#include "hash.h" | |
31 | 32 | |
32 | 33 | static size_t size; |
33 | 34 | |
34 | 35 | static |
35 | 36 | inline |
36 | 37 | void |
37 | -addHeaderSize(const void * node, const VISIT which, const int depth) | |
38 | +addHeaderSize(const void * node) | |
38 | 39 | { |
39 | - if (endorder == which || leaf == which) { | |
40 | - size += (*(HttpHeader *)node)->size; | |
41 | - } | |
40 | + size += ((HttpHeader)node)->size; | |
42 | 41 | } |
43 | 42 | |
44 | 43 | size_t |
... | ... | @@ -46,7 +45,7 @@ httpMessageHeaderSizeGet(HttpMessage message) |
46 | 45 | { |
47 | 46 | size = httpIntroSizeGet(message); |
48 | 47 | |
49 | - twalk(message->header, addHeaderSize); | |
48 | + hashEach(message->header, addHeaderSize); | |
50 | 49 | size += 2; |
51 | 50 | |
52 | 51 | return size; | ... | ... |
... | ... | @@ -27,15 +27,16 @@ |
27 | 27 | #include "http/response.h" |
28 | 28 | #include "http/header.h" |
29 | 29 | #include "interface/http_intro.h" |
30 | +#include "hash.h" | |
30 | 31 | |
31 | 32 | static char * string; |
32 | 33 | |
34 | +static | |
35 | +inline | |
33 | 36 | void |
34 | -addHeaderString(const void * node, const VISIT which, const int depth) | |
37 | +addHeaderString(const void * node) | |
35 | 38 | { |
36 | - if (endorder == which || leaf == which) { | |
37 | - string += httpHeaderToString(*(HttpHeader *)node, string); | |
38 | - } | |
39 | + string += httpHeaderToString((HttpHeader)node, string); | |
39 | 40 | } |
40 | 41 | |
41 | 42 | char * |
... | ... | @@ -45,7 +46,7 @@ httpMessageHeaderToString(HttpMessage response, char * _string) |
45 | 46 | |
46 | 47 | string = httpIntroToString(response, _string); |
47 | 48 | |
48 | - twalk(message->header, addHeaderString); | |
49 | + hashEach(message->header, addHeaderString); | |
49 | 50 | |
50 | 51 | *string++ = '\r'; |
51 | 52 | *string++ = '\n'; | ... | ... |
... | ... | @@ -29,6 +29,7 @@ |
29 | 29 | #include "http/header.h" |
30 | 30 | #include "http/parser.h" |
31 | 31 | #include "http/message.h" |
32 | +#include "hash.h" | |
32 | 33 | |
33 | 34 | #define MAX(x,y) ((x) > (y) ? (x) : (y)) |
34 | 35 | |
... | ... | @@ -66,8 +67,7 @@ httpParserHeader( |
66 | 67 | current->dbody = 0; |
67 | 68 | } |
68 | 69 | |
69 | - httpHeaderAdd( | |
70 | - &(current->header), | |
70 | + hashAdd(current->header, | |
71 | 71 | new(HttpHeader, name, nname, value, lend - value)); |
72 | 72 | } |
73 | 73 | ... | ... |
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | #include "http/header.h" |
31 | 31 | |
32 | 32 | #include "utils/memory.h" |
33 | +#include "hash.h" | |
33 | 34 | |
34 | 35 | HttpResponse |
35 | 36 | httpResponse304( |
... | ... | @@ -47,11 +48,11 @@ httpResponse304( |
47 | 48 | message->nbody = 0; |
48 | 49 | message->body = NULL; |
49 | 50 | |
50 | - httpHeaderAdd(&(message->header), | |
51 | + hashAdd(message->header, | |
51 | 52 | new(HttpHeader, CSTRA("Content-Type"), mime, nmime)); |
52 | - httpHeaderAdd(&(message->header), | |
53 | + hashAdd(message->header, | |
53 | 54 | new(HttpHeader, CSTRA("ETag"), etag, netag)); |
54 | - httpHeaderAdd(&(message->header), | |
55 | + hashAdd(message->header, | |
55 | 56 | new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime)); |
56 | 57 | |
57 | 58 | return response; | ... | ... |
... | ... | @@ -33,6 +33,7 @@ |
33 | 33 | #include "http/header.h" |
34 | 34 | |
35 | 35 | #include "utils/memory.h" |
36 | +#include "hash.h" | |
36 | 37 | |
37 | 38 | #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ |
38 | 39 | "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ |
... | ... | @@ -52,7 +53,7 @@ httpResponse404() |
52 | 53 | response = new(HttpResponse, "HTTP/1.1", 404, "Not Found"); |
53 | 54 | message = (HttpMessage)response; |
54 | 55 | |
55 | - httpHeaderAdd(&(message->header), | |
56 | + hashAdd(message->header, | |
56 | 57 | new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); |
57 | 58 | |
58 | 59 | message->type = HTTP_MESSAGE_BUFFERED; | ... | ... |
... | ... | @@ -35,7 +35,7 @@ |
35 | 35 | #include "http/header.h" |
36 | 36 | |
37 | 37 | #include "utils/memory.h" |
38 | - | |
38 | +#include "hash.h" | |
39 | 39 | |
40 | 40 | HttpResponse |
41 | 41 | httpResponseAsset( |
... | ... | @@ -73,11 +73,11 @@ httpResponseAsset( |
73 | 73 | message->handle = new(Stream, STREAM_FD, handle); |
74 | 74 | message->nbody = st.st_size; |
75 | 75 | |
76 | - httpHeaderAdd(&(message->header), | |
76 | + hashAdd(message->header, | |
77 | 77 | new(HttpHeader, CSTRA("Content-Type"), mime, nmime)); |
78 | - httpHeaderAdd(&(message->header), | |
78 | + hashAdd(message->header, | |
79 | 79 | new(HttpHeader, CSTRA("ETag"), etag, netag)); |
80 | - httpHeaderAdd(&(message->header), | |
80 | + hashAdd(message->header, | |
81 | 81 | new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime)); |
82 | 82 | |
83 | 83 | return response; | ... | ... |
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | #include "http/header.h" |
35 | 35 | |
36 | 36 | #include "utils/memory.h" |
37 | +#include "hash.h" | |
37 | 38 | |
38 | 39 | #define RESP_DATA "<form action=\"/me/\" method=\"POST\">" \ |
39 | 40 | "<input name=\"username\" type=\"text\" />" \ |
... | ... | @@ -49,7 +50,7 @@ httpResponseLoginForm() |
49 | 50 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
50 | 51 | message = (HttpMessage)response; |
51 | 52 | |
52 | - httpHeaderAdd(&(message->header), | |
53 | + hashAdd(message->header, | |
53 | 54 | new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); |
54 | 55 | |
55 | 56 | message->type = HTTP_MESSAGE_BUFFERED; | ... | ... |
src/http/response/me.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 <stdlib.h> | |
24 | -#include <string.h> | |
25 | -#include <stdio.h> | |
26 | -#include <time.h> | |
27 | -#include <sys/types.h> | |
28 | - | |
29 | -#include "class.h" | |
30 | -#include "interface/class.h" | |
31 | - | |
32 | -#include "http/response.h" | |
33 | -#include "http/message.h" | |
34 | -#include "http/header.h" | |
35 | - | |
36 | -#include "utils/memory.h" | |
37 | - | |
38 | - | |
39 | -#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ | |
40 | - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ | |
41 | - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ | |
42 | - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" \ | |
43 | - "<head>" \ | |
44 | - "<title>My own little Web-App</title>" \ | |
45 | - "<style type=\"text/css\">" \ | |
46 | - "div#randval {" \ | |
47 | - "left: 200px;" \ | |
48 | - "top: 100px;" \ | |
49 | - "position: fixed;" \ | |
50 | - "background-color: white;" \ | |
51 | - "border: 1px solid black;" \ | |
52 | - "}" \ | |
53 | - "div.hide#randval {" \ | |
54 | - "top: -500px;" \ | |
55 | - "}" \ | |
56 | - ".small {" \ | |
57 | - "font-size: small;" \ | |
58 | - "}" \ | |
59 | - "</style>" \ | |
60 | - "<script type=\"text/javascript\" src=\"/assets/js/jquery\"></script>" \ | |
61 | - "<script type=\"text/javascript\" src=\"/assets/js/serverval\"></script>" \ | |
62 | - "<script>" \ | |
63 | - "$(document).ready(function() {" \ | |
64 | - "var sval = new ServerVal(\"#randval\");" \ | |
65 | - "$(\"a\").click(function() {" \ | |
66 | - "sval.start();" \ | |
67 | - "});" \ | |
68 | - "});" \ | |
69 | - "</script>" \ | |
70 | - "</head>" \ | |
71 | - "<body>" | |
72 | - "<ul id=\"menu\">" \ | |
73 | - "<li>serverval</li>" \ | |
74 | - "</ul>" \ | |
75 | - "<div id=\"randval\" class=\"hide\">" \ | |
76 | - "<span class=\"small\">" \ | |
77 | - "Value created at: <br /><span></span><br>" \ | |
78 | - "Next value in: <span></span><br />" \ | |
79 | - "</span>" \ | |
80 | - "Value: <span></span>" \ | |
81 | - "</div>" \ | |
82 | - "<div id=\"main\">" \ | |
83 | - "<h1>Testpage</h1>" \ | |
84 | - "Welcome %s<br />" \ | |
85 | - "<img src=\"/image/\" />" \ | |
86 | - "</div>" \ | |
87 | - "<hr /><div id=\"msg\"></div>" \ | |
88 | - "</body>" \ | |
89 | - "</html>" | |
90 | - | |
91 | -HttpResponse | |
92 | -httpResponseMe(char * uname) | |
93 | -{ | |
94 | - HttpResponse response; | |
95 | - HttpMessage message; | |
96 | - | |
97 | - response = new(HttpResponse, "HTTP/1.1", 200, "OK"); | |
98 | - message = (HttpMessage)response; | |
99 | - | |
100 | - httpHeaderAdd(&(message->header), | |
101 | - new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); | |
102 | - httpHeaderAdd(&(message->header), | |
103 | - new(HttpHeader, CSTRA("Set-Cookie"), CSTRA("name=Georg+Hopp"))); | |
104 | - httpHeaderAdd(&(message->header), | |
105 | - new(HttpHeader, CSTRA("Set-Cookie"), CSTRA("profession=coder"))); | |
106 | - | |
107 | - message->type = HTTP_MESSAGE_BUFFERED; | |
108 | - message->nbody = sizeof(RESP_DATA)-1-2+strlen(uname); //!< the two are the %s | |
109 | - message->body = malloc(message->nbody+1); | |
110 | - sprintf(message->body, RESP_DATA, uname); | |
111 | - //memcpy(message->body, RESP_DATA, sizeof(RESP_DATA)-1); | |
112 | - | |
113 | - return response; | |
114 | -} | |
115 | - | |
116 | -// vim: set ts=4 sw=4: |
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | #include "http/header.h" |
35 | 35 | |
36 | 36 | #include "utils/memory.h" |
37 | +#include "hash.h" | |
37 | 38 | |
38 | 39 | #define RESP_DATA "{\"ctime\":%ld,\"vnext\":%ld,\"value\":\"%02d\"}" |
39 | 40 | |
... | ... | @@ -49,7 +50,7 @@ httpResponseRandval(time_t ctime, int value) |
49 | 50 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
50 | 51 | message = (HttpMessage)response; |
51 | 52 | |
52 | - httpHeaderAdd(&(message->header), | |
53 | + hashAdd(message->header, | |
53 | 54 | new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); |
54 | 55 | |
55 | 56 | message->type = HTTP_MESSAGE_BUFFERED; | ... | ... |
... | ... | @@ -35,6 +35,7 @@ |
35 | 35 | #include "session.h" |
36 | 36 | |
37 | 37 | #include "utils/memory.h" |
38 | +#include "hash.h" | |
38 | 39 | |
39 | 40 | #define RESP_DATA "{\"id\":\"%lu\",\"timeout\":%d,\"timeleft\":%ld,\"username\":\"%s\"}" |
40 | 41 | |
... | ... | @@ -49,7 +50,7 @@ httpResponseSession(Session session) |
49 | 50 | response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
50 | 51 | message = (HttpMessage)response; |
51 | 52 | |
52 | - httpHeaderAdd(&(message->header), | |
53 | + hashAdd(message->header, | |
53 | 54 | new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); |
54 | 55 | |
55 | 56 | message->type = HTTP_MESSAGE_BUFFERED; | ... | ... |
... | ... | @@ -5,9 +5,11 @@ |
5 | 5 | #include "interface/class.h" |
6 | 6 | |
7 | 7 | #include "http/message.h" |
8 | +#include "http/header.h" | |
8 | 9 | #include "http/response.h" |
9 | 10 | |
10 | 11 | #include "utils/memory.h" |
12 | +#include "hash.h" | |
11 | 13 | |
12 | 14 | void |
13 | 15 | httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) |
... | ... | @@ -18,17 +20,15 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) |
18 | 20 | size_t nbuf; |
19 | 21 | |
20 | 22 | if (httpMessageHasKeepAlive(request)) { |
21 | - httpHeaderAdd( | |
22 | - &(response->header), | |
23 | + hashAdd(response->header, | |
23 | 24 | new(HttpHeader, CSTRA("Connection"), CSTRA("Keep-Alive"))); |
24 | 25 | } |
25 | 26 | else { |
26 | - httpHeaderAdd( | |
27 | - &(response->header), | |
27 | + hashAdd(response->header, | |
28 | 28 | new(HttpHeader, CSTRA("Connection"), CSTRA("Close"))); |
29 | 29 | } |
30 | 30 | |
31 | - httpHeaderAdd(&(response->header), | |
31 | + hashAdd(response->header, | |
32 | 32 | new(HttpHeader, CSTRA("Server"), CSTRA("testserver"))); |
33 | 33 | |
34 | 34 | switch(((HttpResponse)response)->status) { |
... | ... | @@ -37,14 +37,14 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) |
37 | 37 | |
38 | 38 | default: |
39 | 39 | nbuf = sprintf(buffer, "%d", response->nbody); |
40 | - httpHeaderAdd(&(response->header), | |
40 | + hashAdd(response->header, | |
41 | 41 | new(HttpHeader, CSTRA("Content-Length"), buffer, nbuf)); |
42 | 42 | } |
43 | 43 | |
44 | 44 | t = time(NULL); |
45 | 45 | tmp = localtime(&t); |
46 | 46 | nbuf = strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); |
47 | - httpHeaderAdd(&(response->header), | |
47 | + hashAdd(response->header, | |
48 | 48 | new(HttpHeader, CSTRA("Date"), buffer, nbuf)); |
49 | 49 | } |
50 | 50 | ... | ... |
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | #include "http/response.h" |
7 | 7 | |
8 | 8 | #include "utils/memory.h" |
9 | +#include "hash.h" | |
9 | 10 | |
10 | 11 | HttpMessage |
11 | 12 | httpWorkerGetAsset( |
... | ... | @@ -18,8 +19,8 @@ httpWorkerGetAsset( |
18 | 19 | size_t nmatch; |
19 | 20 | HttpHeader header; |
20 | 21 | |
21 | - header = httpHeaderGet( | |
22 | - &(((HttpMessage)request)->header), | |
22 | + header = hashGet( | |
23 | + ((HttpMessage)request)->header, | |
23 | 24 | CSTRA("If-None-Match")); |
24 | 25 | |
25 | 26 | if (NULL == header) { | ... | ... |
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | #include "interface/class.h" |
31 | 31 | |
32 | 32 | #include "http/worker.h" |
33 | +#include "http/header.h" | |
33 | 34 | #include "http/message.h" |
34 | 35 | #include "http/request.h" |
35 | 36 | #include "http/response.h" |
... | ... | @@ -39,6 +40,7 @@ |
39 | 40 | #include "stream.h" |
40 | 41 | |
41 | 42 | #include "utils/memory.h" |
43 | +#include "hash.h" | |
42 | 44 | |
43 | 45 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); |
44 | 46 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); |
... | ... | @@ -60,8 +62,8 @@ httpWorkerProcess(HttpWorker this, Stream st) |
60 | 62 | HttpMessage rmessage = reqq->msgs[i]; |
61 | 63 | HttpRequest request = (HttpRequest)(reqq->msgs[i]); |
62 | 64 | HttpMessage response = NULL; |
63 | - HttpHeader cookie = httpHeaderGet( | |
64 | - &(rmessage->header), | |
65 | + HttpHeader cookie = hashGet( | |
66 | + rmessage->header, | |
65 | 67 | CSTRA("cookie")); |
66 | 68 | |
67 | 69 | if (NULL == this->session && NULL != cookie) { |
... | ... | @@ -111,8 +113,7 @@ httpWorkerProcess(HttpWorker this, Stream st) |
111 | 113 | |
112 | 114 | response = (HttpMessage)httpResponseSession(this->session); |
113 | 115 | |
114 | - httpHeaderAdd( | |
115 | - &(response->header), | |
116 | + hashAdd(response->header, | |
116 | 117 | new(HttpHeader, CSTRA("Set-Cookie"), buffer, nbuf)); |
117 | 118 | } |
118 | 119 | } | ... | ... |
1 | 1 | /** |
2 | 2 | * \file |
3 | - * Get a header from a tree containing headers by its name. | |
4 | - * The key for the tree is the hased lowercase header identifier. | |
5 | 3 | * |
6 | 4 | * \author Georg Hopp |
7 | 5 | * |
8 | 6 | * \copyright |
9 | - * Copyright (C) 2012 Georg Hopp | |
7 | + * Copyright © 2012 Georg Hopp | |
10 | 8 | * |
11 | 9 | * This program is free software: you can redistribute it and/or modify |
12 | 10 | * it under the terms of the GNU General Public License as published by |
... | ... | @@ -22,30 +20,32 @@ |
22 | 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
23 | 21 | */ |
24 | 22 | |
25 | -#include <search.h> | |
26 | 23 | #include <stdlib.h> |
24 | +#include <stdio.h> | |
25 | +#include <stdarg.h> | |
27 | 26 | |
28 | -#include "http/header.h" | |
29 | -#include "utils/hash.h" | |
27 | +#include "class.h" | |
28 | +#include "interface/hashable.h" | |
30 | 29 | |
31 | -static | |
32 | -inline | |
33 | -int | |
34 | -comp(const void * _a, const void * _b) | |
35 | -{ | |
36 | - const unsigned long * a = _a; | |
37 | - HttpHeader b = (HttpHeader)_b; | |
38 | - return (*a < b->hash)? -1 : (*a > b->hash)? 1 : 0; | |
39 | -} | |
30 | +const struct interface i_Hashable = { | |
31 | + "hashable", | |
32 | + 2 | |
33 | +}; | |
40 | 34 | |
41 | -HttpHeader | |
42 | -httpHeaderGet(const HttpHeader * root, const char * name, size_t nname) | |
35 | +unsigned long | |
36 | +hashableGetHash(void * hashable) | |
43 | 37 | { |
44 | - unsigned long hash = sdbm((const unsigned char*)name, nname); | |
38 | + unsigned long ret; | |
45 | 39 | |
46 | - HttpHeader * found = tfind(&hash, (void**)root, comp); | |
40 | + RETCALL(hashable, Hashable, getHash, ret); | |
47 | 41 | |
48 | - return (NULL != found)? *found : NULL; | |
42 | + return ret; | |
43 | +} | |
44 | + | |
45 | +void | |
46 | +hashableHandleDouble(void * hashable, void * new_hashable) | |
47 | +{ | |
48 | + CALL(hashable, Hashable, handleDouble, new_hashable); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | // vim: set ts=4 sw=4: | ... | ... |
Please
register
or
login
to post a comment