Commit 646d1e1c50ad972e8098c2b23e531d58a043c181

Authored by Georg Hopp
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
  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,8 +41,6 @@ CLASS(HttpHeader) {
41 size_t size; //!< full size of this header 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 size_t httpHeaderToString(HttpHeader, char *); 44 size_t httpHeaderToString(HttpHeader, char *);
47 45
48 #endif // __HTTP_HEADER_H__ 46 #endif // __HTTP_HEADER_H__
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 #define __HTTP_MESSAGE__ 25 #define __HTTP_MESSAGE__
26 26
27 #include "class.h" 27 #include "class.h"
28 -#include "http/header.h" 28 +#include "hash.h"
29 #include "stream.h" 29 #include "stream.h"
30 30
31 typedef enum e_HttpMessageType { 31 typedef enum e_HttpMessageType {
@@ -37,7 +37,7 @@ typedef enum e_HttpMessageType { @@ -37,7 +37,7 @@ typedef enum e_HttpMessageType {
37 CLASS(HttpMessage) { 37 CLASS(HttpMessage) {
38 char * version; 38 char * version;
39 39
40 - HttpHeader header; 40 + Hash header;
41 41
42 HttpMessageType type; 42 HttpMessageType type;
43 Stream handle; 43 Stream handle;
  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 +6,12 @@ IFACE = interface/class.c interface/stream_reader.c interface/logger.c \
6 interface/subject.c interface/observer.c interface.c 6 interface/subject.c interface/observer.c interface.c
7 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c 7 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
8 STREAM = stream.c stream/read.c stream/write.c 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 SERVER = server.c server/run.c server/close_conn.c server/poll.c \ 15 SERVER = server.c server/run.c server/close_conn.c server/poll.c \
10 server/handle_accept.c server/read.c server/write.c 16 server/handle_accept.c server/read.c server/write.c
11 LOGGER = logger.c logger/stderr.c logger/syslog.c 17 LOGGER = logger.c logger/stderr.c logger/syslog.c
@@ -44,7 +50,7 @@ WORKER = http/worker.c \ @@ -44,7 +50,7 @@ WORKER = http/worker.c \
44 http/worker/write.c \ 50 http/worker/write.c \
45 http/worker/get_asset.c \ 51 http/worker/get_asset.c \
46 http/worker/add_common_header.c 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 http/header/to_string.c 54 http/header/to_string.c
49 SESSION = session.c session/add.c session/get.c session/delete.c 55 SESSION = session.c session/add.c session/get.c session/delete.c
50 UTILS = utils/hash.c \ 56 UTILS = utils/hash.c \
@@ -61,6 +67,6 @@ bin_PROGRAMS = webgameserver @@ -61,6 +67,6 @@ bin_PROGRAMS = webgameserver
61 webgameserver_SOURCES = webgameserver.c \ 67 webgameserver_SOURCES = webgameserver.c \
62 $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ 68 $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \
63 $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ 69 $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \
64 - $(UTILS) $(MSGQ) $(SESSION) $(STREAM) 70 + $(UTILS) $(MSGQ) $(SESSION) $(STREAM) $(HASH)
65 webgameserver_CFLAGS = -Wall -I ../include/ 71 webgameserver_CFLAGS = -Wall -I ../include/
66 webgameserver_LDFLAGS = -lrt -lssl 72 webgameserver_LDFLAGS = -lrt -lssl
  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:
  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:
  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:
  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:
  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,6 +27,7 @@
27 #include "class.h" 27 #include "class.h"
28 #include "interface/class.h" 28 #include "interface/class.h"
29 #include "http/header.h" 29 #include "http/header.h"
  30 +#include "interface/hashable.h"
30 31
31 #include "utils/hash.h" 32 #include "utils/hash.h"
32 #include "utils/memory.h" 33 #include "utils/memory.h"
@@ -72,7 +73,35 @@ httpHeaderDtor(void * _this) @@ -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 INIT_IFACE(Class, httpHeaderCtor, httpHeaderDtor, NULL); 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 // vim: set ts=4 sw=4: 107 // vim: set ts=4 sw=4:
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,20 +32,12 @@
32 32
33 #include "class.h" 33 #include "class.h"
34 #include "interface/class.h" 34 #include "interface/class.h"
35 - 35 +#include "hash.h"
36 #include "http/message.h" 36 #include "http/message.h"
37 #include "utils/memory.h" 37 #include "utils/memory.h"
38 38
39 39
40 static 40 static
41 -inline  
42 -void  
43 -tDelete(void * node)  
44 -{  
45 - delete(node);  
46 -}  
47 -  
48 -static  
49 int 41 int
50 httpMessageCtor(void * _this, va_list * params) 42 httpMessageCtor(void * _this, va_list * params)
51 { 43 {
@@ -55,6 +47,8 @@ httpMessageCtor(void * _this, va_list * params) @@ -55,6 +47,8 @@ httpMessageCtor(void * _this, va_list * params)
55 this->version = calloc(1, strlen(version)+1); 47 this->version = calloc(1, strlen(version)+1);
56 strcpy(this->version, version); 48 strcpy(this->version, version);
57 49
  50 + this->header = new(Hash);
  51 +
58 return 0; 52 return 0;
59 } 53 }
60 54
@@ -64,15 +58,9 @@ httpMessageDtor(void * _this) @@ -64,15 +58,9 @@ httpMessageDtor(void * _this)
64 { 58 {
65 HttpMessage this = _this; 59 HttpMessage this = _this;
66 60
  61 + delete(this->header);
67 FREE(this->version); 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 switch (this->type) { 64 switch (this->type) {
77 case HTTP_MESSAGE_BUFFERED: 65 case HTTP_MESSAGE_BUFFERED:
78 FREE(this->body); 66 FREE(this->body);
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include "utils/memory.h" 31 #include "utils/memory.h"
32 32
33 #include "commons.h" 33 #include "commons.h"
  34 +#include "hash.h"
34 35
35 char 36 char
36 httpMessageHasKeepAlive(HttpMessage message) 37 httpMessageHasKeepAlive(HttpMessage message)
@@ -39,7 +40,7 @@ httpMessageHasKeepAlive(HttpMessage message) @@ -39,7 +40,7 @@ httpMessageHasKeepAlive(HttpMessage message)
39 size_t size; 40 size_t size;
40 char * value; 41 char * value;
41 42
42 - header = httpHeaderGet(&(message->header), CSTRA("connection")); 43 + header = hashGet(message->header, CSTRA("connection"));
43 44
44 if (NULL == header) { 45 if (NULL == header) {
45 return 0; 46 return 0;
@@ -28,17 +28,16 @@ @@ -28,17 +28,16 @@
28 #include "http/response.h" 28 #include "http/response.h"
29 #include "http/header.h" 29 #include "http/header.h"
30 #include "interface/http_intro.h" 30 #include "interface/http_intro.h"
  31 +#include "hash.h"
31 32
32 static size_t size; 33 static size_t size;
33 34
34 static 35 static
35 inline 36 inline
36 void 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 size_t 43 size_t
@@ -46,7 +45,7 @@ httpMessageHeaderSizeGet(HttpMessage message) @@ -46,7 +45,7 @@ httpMessageHeaderSizeGet(HttpMessage message)
46 { 45 {
47 size = httpIntroSizeGet(message); 46 size = httpIntroSizeGet(message);
48 47
49 - twalk(message->header, addHeaderSize); 48 + hashEach(message->header, addHeaderSize);
50 size += 2; 49 size += 2;
51 50
52 return size; 51 return size;
@@ -27,15 +27,16 @@ @@ -27,15 +27,16 @@
27 #include "http/response.h" 27 #include "http/response.h"
28 #include "http/header.h" 28 #include "http/header.h"
29 #include "interface/http_intro.h" 29 #include "interface/http_intro.h"
  30 +#include "hash.h"
30 31
31 static char * string; 32 static char * string;
32 33
  34 +static
  35 +inline
33 void 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 char * 42 char *
@@ -45,7 +46,7 @@ httpMessageHeaderToString(HttpMessage response, char * _string) @@ -45,7 +46,7 @@ httpMessageHeaderToString(HttpMessage response, char * _string)
45 46
46 string = httpIntroToString(response, _string); 47 string = httpIntroToString(response, _string);
47 48
48 - twalk(message->header, addHeaderString); 49 + hashEach(message->header, addHeaderString);
49 50
50 *string++ = '\r'; 51 *string++ = '\r';
51 *string++ = '\n'; 52 *string++ = '\n';
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 #include "http/header.h" 29 #include "http/header.h"
30 #include "http/parser.h" 30 #include "http/parser.h"
31 #include "http/message.h" 31 #include "http/message.h"
  32 +#include "hash.h"
32 33
33 #define MAX(x,y) ((x) > (y) ? (x) : (y)) 34 #define MAX(x,y) ((x) > (y) ? (x) : (y))
34 35
@@ -66,8 +67,7 @@ httpParserHeader( @@ -66,8 +67,7 @@ httpParserHeader(
66 current->dbody = 0; 67 current->dbody = 0;
67 } 68 }
68 69
69 - httpHeaderAdd(  
70 - &(current->header), 70 + hashAdd(current->header,
71 new(HttpHeader, name, nname, value, lend - value)); 71 new(HttpHeader, name, nname, value, lend - value));
72 } 72 }
73 73
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 #include "http/header.h" 30 #include "http/header.h"
31 31
32 #include "utils/memory.h" 32 #include "utils/memory.h"
  33 +#include "hash.h"
33 34
34 HttpResponse 35 HttpResponse
35 httpResponse304( 36 httpResponse304(
@@ -47,11 +48,11 @@ httpResponse304( @@ -47,11 +48,11 @@ httpResponse304(
47 message->nbody = 0; 48 message->nbody = 0;
48 message->body = NULL; 49 message->body = NULL;
49 50
50 - httpHeaderAdd(&(message->header), 51 + hashAdd(message->header,
51 new(HttpHeader, CSTRA("Content-Type"), mime, nmime)); 52 new(HttpHeader, CSTRA("Content-Type"), mime, nmime));
52 - httpHeaderAdd(&(message->header), 53 + hashAdd(message->header,
53 new(HttpHeader, CSTRA("ETag"), etag, netag)); 54 new(HttpHeader, CSTRA("ETag"), etag, netag));
54 - httpHeaderAdd(&(message->header), 55 + hashAdd(message->header,
55 new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime)); 56 new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime));
56 57
57 return response; 58 return response;
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 #include "http/header.h" 33 #include "http/header.h"
34 34
35 #include "utils/memory.h" 35 #include "utils/memory.h"
  36 +#include "hash.h"
36 37
37 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ 38 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \
38 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ 39 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \
@@ -52,7 +53,7 @@ httpResponse404() @@ -52,7 +53,7 @@ httpResponse404()
52 response = new(HttpResponse, "HTTP/1.1", 404, "Not Found"); 53 response = new(HttpResponse, "HTTP/1.1", 404, "Not Found");
53 message = (HttpMessage)response; 54 message = (HttpMessage)response;
54 55
55 - httpHeaderAdd(&(message->header), 56 + hashAdd(message->header,
56 new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); 57 new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html")));
57 58
58 message->type = HTTP_MESSAGE_BUFFERED; 59 message->type = HTTP_MESSAGE_BUFFERED;
@@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
35 #include "http/header.h" 35 #include "http/header.h"
36 36
37 #include "utils/memory.h" 37 #include "utils/memory.h"
38 - 38 +#include "hash.h"
39 39
40 HttpResponse 40 HttpResponse
41 httpResponseAsset( 41 httpResponseAsset(
@@ -73,11 +73,11 @@ httpResponseAsset( @@ -73,11 +73,11 @@ httpResponseAsset(
73 message->handle = new(Stream, STREAM_FD, handle); 73 message->handle = new(Stream, STREAM_FD, handle);
74 message->nbody = st.st_size; 74 message->nbody = st.st_size;
75 75
76 - httpHeaderAdd(&(message->header), 76 + hashAdd(message->header,
77 new(HttpHeader, CSTRA("Content-Type"), mime, nmime)); 77 new(HttpHeader, CSTRA("Content-Type"), mime, nmime));
78 - httpHeaderAdd(&(message->header), 78 + hashAdd(message->header,
79 new(HttpHeader, CSTRA("ETag"), etag, netag)); 79 new(HttpHeader, CSTRA("ETag"), etag, netag));
80 - httpHeaderAdd(&(message->header), 80 + hashAdd(message->header,
81 new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime)); 81 new(HttpHeader, CSTRA("Last-Modified"), mtime, nmtime));
82 82
83 return response; 83 return response;
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 #include "http/header.h" 34 #include "http/header.h"
35 35
36 #include "utils/memory.h" 36 #include "utils/memory.h"
  37 +#include "hash.h"
37 38
38 #define RESP_DATA "<form action=\"/me/\" method=\"POST\">" \ 39 #define RESP_DATA "<form action=\"/me/\" method=\"POST\">" \
39 "<input name=\"username\" type=\"text\" />" \ 40 "<input name=\"username\" type=\"text\" />" \
@@ -49,7 +50,7 @@ httpResponseLoginForm() @@ -49,7 +50,7 @@ httpResponseLoginForm()
49 response = new(HttpResponse, "HTTP/1.1", 200, "OK"); 50 response = new(HttpResponse, "HTTP/1.1", 200, "OK");
50 message = (HttpMessage)response; 51 message = (HttpMessage)response;
51 52
52 - httpHeaderAdd(&(message->header), 53 + hashAdd(message->header,
53 new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); 54 new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html")));
54 55
55 message->type = HTTP_MESSAGE_BUFFERED; 56 message->type = HTTP_MESSAGE_BUFFERED;
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,6 +34,7 @@
34 #include "http/header.h" 34 #include "http/header.h"
35 35
36 #include "utils/memory.h" 36 #include "utils/memory.h"
  37 +#include "hash.h"
37 38
38 #define RESP_DATA "{\"ctime\":%ld,\"vnext\":%ld,\"value\":\"%02d\"}" 39 #define RESP_DATA "{\"ctime\":%ld,\"vnext\":%ld,\"value\":\"%02d\"}"
39 40
@@ -49,7 +50,7 @@ httpResponseRandval(time_t ctime, int value) @@ -49,7 +50,7 @@ httpResponseRandval(time_t ctime, int value)
49 response = new(HttpResponse, "HTTP/1.1", 200, "OK"); 50 response = new(HttpResponse, "HTTP/1.1", 200, "OK");
50 message = (HttpMessage)response; 51 message = (HttpMessage)response;
51 52
52 - httpHeaderAdd(&(message->header), 53 + hashAdd(message->header,
53 new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); 54 new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json")));
54 55
55 message->type = HTTP_MESSAGE_BUFFERED; 56 message->type = HTTP_MESSAGE_BUFFERED;
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 #include "session.h" 35 #include "session.h"
36 36
37 #include "utils/memory.h" 37 #include "utils/memory.h"
  38 +#include "hash.h"
38 39
39 #define RESP_DATA "{\"id\":\"%lu\",\"timeout\":%d,\"timeleft\":%ld,\"username\":\"%s\"}" 40 #define RESP_DATA "{\"id\":\"%lu\",\"timeout\":%d,\"timeleft\":%ld,\"username\":\"%s\"}"
40 41
@@ -49,7 +50,7 @@ httpResponseSession(Session session) @@ -49,7 +50,7 @@ httpResponseSession(Session session)
49 response = new(HttpResponse, "HTTP/1.1", 200, "OK"); 50 response = new(HttpResponse, "HTTP/1.1", 200, "OK");
50 message = (HttpMessage)response; 51 message = (HttpMessage)response;
51 52
52 - httpHeaderAdd(&(message->header), 53 + hashAdd(message->header,
53 new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json"))); 54 new(HttpHeader, CSTRA("Content-Type"), CSTRA("application/json")));
54 55
55 message->type = HTTP_MESSAGE_BUFFERED; 56 message->type = HTTP_MESSAGE_BUFFERED;
@@ -5,9 +5,11 @@ @@ -5,9 +5,11 @@
5 #include "interface/class.h" 5 #include "interface/class.h"
6 6
7 #include "http/message.h" 7 #include "http/message.h"
  8 +#include "http/header.h"
8 #include "http/response.h" 9 #include "http/response.h"
9 10
10 #include "utils/memory.h" 11 #include "utils/memory.h"
  12 +#include "hash.h"
11 13
12 void 14 void
13 httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) 15 httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response)
@@ -18,17 +20,15 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) @@ -18,17 +20,15 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response)
18 size_t nbuf; 20 size_t nbuf;
19 21
20 if (httpMessageHasKeepAlive(request)) { 22 if (httpMessageHasKeepAlive(request)) {
21 - httpHeaderAdd(  
22 - &(response->header), 23 + hashAdd(response->header,
23 new(HttpHeader, CSTRA("Connection"), CSTRA("Keep-Alive"))); 24 new(HttpHeader, CSTRA("Connection"), CSTRA("Keep-Alive")));
24 } 25 }
25 else { 26 else {
26 - httpHeaderAdd(  
27 - &(response->header), 27 + hashAdd(response->header,
28 new(HttpHeader, CSTRA("Connection"), CSTRA("Close"))); 28 new(HttpHeader, CSTRA("Connection"), CSTRA("Close")));
29 } 29 }
30 30
31 - httpHeaderAdd(&(response->header), 31 + hashAdd(response->header,
32 new(HttpHeader, CSTRA("Server"), CSTRA("testserver"))); 32 new(HttpHeader, CSTRA("Server"), CSTRA("testserver")));
33 33
34 switch(((HttpResponse)response)->status) { 34 switch(((HttpResponse)response)->status) {
@@ -37,14 +37,14 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response) @@ -37,14 +37,14 @@ httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response)
37 37
38 default: 38 default:
39 nbuf = sprintf(buffer, "%d", response->nbody); 39 nbuf = sprintf(buffer, "%d", response->nbody);
40 - httpHeaderAdd(&(response->header), 40 + hashAdd(response->header,
41 new(HttpHeader, CSTRA("Content-Length"), buffer, nbuf)); 41 new(HttpHeader, CSTRA("Content-Length"), buffer, nbuf));
42 } 42 }
43 43
44 t = time(NULL); 44 t = time(NULL);
45 tmp = localtime(&t); 45 tmp = localtime(&t);
46 nbuf = strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); 46 nbuf = strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
47 - httpHeaderAdd(&(response->header), 47 + hashAdd(response->header,
48 new(HttpHeader, CSTRA("Date"), buffer, nbuf)); 48 new(HttpHeader, CSTRA("Date"), buffer, nbuf));
49 } 49 }
50 50
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 #include "http/response.h" 6 #include "http/response.h"
7 7
8 #include "utils/memory.h" 8 #include "utils/memory.h"
  9 +#include "hash.h"
9 10
10 HttpMessage 11 HttpMessage
11 httpWorkerGetAsset( 12 httpWorkerGetAsset(
@@ -18,8 +19,8 @@ httpWorkerGetAsset( @@ -18,8 +19,8 @@ httpWorkerGetAsset(
18 size_t nmatch; 19 size_t nmatch;
19 HttpHeader header; 20 HttpHeader header;
20 21
21 - header = httpHeaderGet(  
22 - &(((HttpMessage)request)->header), 22 + header = hashGet(
  23 + ((HttpMessage)request)->header,
23 CSTRA("If-None-Match")); 24 CSTRA("If-None-Match"));
24 25
25 if (NULL == header) { 26 if (NULL == header) {
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 #include "interface/class.h" 30 #include "interface/class.h"
31 31
32 #include "http/worker.h" 32 #include "http/worker.h"
  33 +#include "http/header.h"
33 #include "http/message.h" 34 #include "http/message.h"
34 #include "http/request.h" 35 #include "http/request.h"
35 #include "http/response.h" 36 #include "http/response.h"
@@ -39,6 +40,7 @@ @@ -39,6 +40,7 @@
39 #include "stream.h" 40 #include "stream.h"
40 41
41 #include "utils/memory.h" 42 #include "utils/memory.h"
  43 +#include "hash.h"
42 44
43 HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); 45 HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t);
44 void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); 46 void httpWorkerAddCommonHeader(HttpMessage, HttpMessage);
@@ -60,8 +62,8 @@ httpWorkerProcess(HttpWorker this, Stream st) @@ -60,8 +62,8 @@ httpWorkerProcess(HttpWorker this, Stream st)
60 HttpMessage rmessage = reqq->msgs[i]; 62 HttpMessage rmessage = reqq->msgs[i];
61 HttpRequest request = (HttpRequest)(reqq->msgs[i]); 63 HttpRequest request = (HttpRequest)(reqq->msgs[i]);
62 HttpMessage response = NULL; 64 HttpMessage response = NULL;
63 - HttpHeader cookie = httpHeaderGet(  
64 - &(rmessage->header), 65 + HttpHeader cookie = hashGet(
  66 + rmessage->header,
65 CSTRA("cookie")); 67 CSTRA("cookie"));
66 68
67 if (NULL == this->session && NULL != cookie) { 69 if (NULL == this->session && NULL != cookie) {
@@ -111,8 +113,7 @@ httpWorkerProcess(HttpWorker this, Stream st) @@ -111,8 +113,7 @@ httpWorkerProcess(HttpWorker this, Stream st)
111 113
112 response = (HttpMessage)httpResponseSession(this->session); 114 response = (HttpMessage)httpResponseSession(this->session);
113 115
114 - httpHeaderAdd(  
115 - &(response->header), 116 + hashAdd(response->header,
116 new(HttpHeader, CSTRA("Set-Cookie"), buffer, nbuf)); 117 new(HttpHeader, CSTRA("Set-Cookie"), buffer, nbuf));
117 } 118 }
118 } 119 }
1 /** 1 /**
2 * \file 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 * \author Georg Hopp 4 * \author Georg Hopp
7 * 5 *
8 * \copyright 6 * \copyright
9 - * Copyright (C) 2012 Georg Hopp 7 + * Copyright © 2012 Georg Hopp
10 * 8 *
11 * This program is free software: you can redistribute it and/or modify 9 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -22,30 +20,32 @@ @@ -22,30 +20,32 @@
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */ 21 */
24 22
25 -#include <search.h>  
26 #include <stdlib.h> 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 // vim: set ts=4 sw=4: 51 // vim: set ts=4 sw=4:
Please register or login to post a comment