Browse Source
Added a new abstraction: hash. A a lot of things within http are key/value things 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
master
Added a new abstraction: hash. A a lot of things within http are key/value things 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
master
28 changed files with 325 additions and 267 deletions
-
20include/hash.h
-
2include/http/header.h
-
4include/http/message.h
-
38include/interface/hashable.h
-
10src/Makefile.am
-
42src/hash.c
-
32src/hash/add.c
-
25src/hash/delete.c
-
25src/hash/each.c
-
25src/hash/get.c
-
31src/http/header.c
-
69src/http/header/add.c
-
20src/http/message.c
-
3src/http/message/has_keep_alive.c
-
9src/http/message/header_size_get.c
-
11src/http/message/header_to_string.c
-
4src/http/parser/header.c
-
7src/http/response/304.c
-
3src/http/response/404.c
-
8src/http/response/asset.c
-
3src/http/response/login_form.c
-
116src/http/response/me.c
-
3src/http/response/randval.c
-
3src/http/response/session.c
-
14src/http/worker/add_common_header.c
-
5src/http/worker/get_asset.c
-
9src/http/worker/process.c
-
51src/interface/hashable.c
@ -0,0 +1,20 @@ |
|||||
|
#ifndef __HASH_H__ |
||||
|
#define __HASH_H__ |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
#include "class.h" |
||||
|
|
||||
|
|
||||
|
CLASS(Hash) { |
||||
|
void * root; |
||||
|
}; |
||||
|
|
||||
|
void * hashAdd(Hash, void *); |
||||
|
void * hashDelete(Hash, const char *, size_t); |
||||
|
void * hashGet(Hash, const char *, size_t); |
||||
|
void hashEach(Hash, void (*)(const void*)); |
||||
|
|
||||
|
#endif // __HASH_H__ |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,42 @@ |
|||||
|
#define _GNU_SOURCE |
||||
|
|
||||
|
#include <search.h> |
||||
|
#include <stdarg.h> |
||||
|
|
||||
|
#include "hash.h" |
||||
|
#include "class.h" |
||||
|
#include "interface/class.h" |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
hashCtor(void * _this, va_list * params) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
inline |
||||
|
void |
||||
|
tDelete(void * node) |
||||
|
{ |
||||
|
delete(node); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
hashDtor(void * _this) |
||||
|
{ |
||||
|
Hash this = _this; |
||||
|
|
||||
|
/** |
||||
|
* this is a GNU extension...anyway on most non |
||||
|
* GNUish systems i would not use tsearch anyway |
||||
|
* as the trees will be unbalanced. |
||||
|
*/ |
||||
|
tdestroy(this->root, tDelete); |
||||
|
} |
||||
|
|
||||
|
INIT_IFACE(Class, hashCtor, hashDtor, NULL); |
||||
|
CREATE_CLASS(Hash, NULL, IFACE(Class)); |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,32 @@ |
|||||
|
#include <search.h> |
||||
|
|
||||
|
#include "hash.h" |
||||
|
#include "interface/hashable.h" |
||||
|
#include "interface/class.h" |
||||
|
|
||||
|
static |
||||
|
inline |
||||
|
int |
||||
|
hashAddComp(const void * a, const void * b) |
||||
|
{ |
||||
|
return hashableGetHash((void*)b) - hashableGetHash((void*)a); |
||||
|
} |
||||
|
|
||||
|
void * |
||||
|
hashAdd(Hash this, void * operand) |
||||
|
{ |
||||
|
void * found = tsearch(operand, &(this->root), hashAddComp); |
||||
|
|
||||
|
if (NULL == found) { |
||||
|
return NULL; |
||||
|
} |
||||
|
|
||||
|
if (operand != *(void**)found) { |
||||
|
hashableHandleDouble(*(void**)found, operand); |
||||
|
delete(operand); |
||||
|
} |
||||
|
|
||||
|
return *(void**)found; |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,25 @@ |
|||||
|
#include <search.h> |
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
#include "hash.h" |
||||
|
#include "interface/hashable.h" |
||||
|
#include "utils/hash.h" |
||||
|
|
||||
|
static |
||||
|
inline |
||||
|
int |
||||
|
hashDeleteComp(const void * a, const void * b) |
||||
|
{ |
||||
|
return hashableGetHash((void*)b) - *(const unsigned long*)a; |
||||
|
} |
||||
|
|
||||
|
void * |
||||
|
hashDelete(Hash this, const char * search, size_t nsearch) |
||||
|
{ |
||||
|
unsigned long hash = sdbm((const unsigned char *)search, nsearch); |
||||
|
void * found = tfind(&hash, &(this->root), hashDeleteComp); |
||||
|
|
||||
|
return (NULL != found)? *(void**)found : NULL; |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,25 @@ |
|||||
|
#include <search.h> |
||||
|
|
||||
|
#include "hash.h" |
||||
|
|
||||
|
static void (*cb)(void*); |
||||
|
|
||||
|
static |
||||
|
inline |
||||
|
void |
||||
|
walk(const void * node, const VISIT which, const int depth) |
||||
|
{ |
||||
|
if (endorder == which || leaf == which) { |
||||
|
cb(*(void**)node); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
hashEach(Hash this, void (*callback)(const void*)) |
||||
|
{ |
||||
|
cb = callback; |
||||
|
|
||||
|
twalk(this->root, walk); |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,25 @@ |
|||||
|
#include <search.h> |
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
#include "hash.h" |
||||
|
#include "interface/hashable.h" |
||||
|
#include "utils/hash.h" |
||||
|
|
||||
|
static |
||||
|
inline |
||||
|
int |
||||
|
hashGetComp(const void * a, const void * b) |
||||
|
{ |
||||
|
return hashableGetHash((void*)b) - *(const unsigned long*)a; |
||||
|
} |
||||
|
|
||||
|
void * |
||||
|
hashGet(Hash this, const char * search, size_t nsearch) |
||||
|
{ |
||||
|
unsigned long hash = sdbm((const unsigned char *)search, nsearch); |
||||
|
void * found = tfind(&hash, &(this->root), hashGetComp); |
||||
|
|
||||
|
return (NULL != found)? *(void**)found : NULL; |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -1,69 +0,0 @@ |
|||||
/** |
|
||||
* \file |
|
||||
* |
|
||||
* \author Georg Hopp |
|
||||
* |
|
||||
* \copyright |
|
||||
* Copyright (C) 2012 Georg Hopp |
|
||||
* |
|
||||
* This program is free software: you can redistribute it and/or modify |
|
||||
* it under the terms of the GNU General Public License as published by |
|
||||
* the Free Software Foundation, either version 3 of the License, or |
|
||||
* (at your option) any later version. |
|
||||
* |
|
||||
* This program is distributed in the hope that it will be useful, |
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
* GNU General Public License for more details. |
|
||||
* |
|
||||
* You should have received a copy of the GNU General Public License |
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
||||
*/ |
|
||||
|
|
||||
#include <search.h> |
|
||||
#include <stdio.h> |
|
||||
#include <stdlib.h> |
|
||||
#include <string.h> |
|
||||
|
|
||||
#include "class.h" |
|
||||
#include "interface/class.h" |
|
||||
#include "http/header.h" |
|
||||
#include "utils/hash.h" |
|
||||
|
|
||||
static |
|
||||
inline |
|
||||
int |
|
||||
comp(const void * _a, const void * _b) |
|
||||
{ |
|
||||
HttpHeader a = (HttpHeader)_a; |
|
||||
HttpHeader b = (HttpHeader)_b; |
|
||||
return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0; |
|
||||
} |
|
||||
|
|
||||
HttpHeader |
|
||||
httpHeaderAdd(const HttpHeader * root, HttpHeader header) |
|
||||
{ |
|
||||
HttpHeader * _found = tsearch(header, (void **)root, comp); |
|
||||
HttpHeader found; |
|
||||
|
|
||||
if (NULL == _found) { |
|
||||
return NULL; |
|
||||
} |
|
||||
|
|
||||
found = *_found; |
|
||||
|
|
||||
if (found != header) { |
|
||||
if (found->cvalue >= N_VALUES) { |
|
||||
return NULL; |
|
||||
} |
|
||||
(found->nvalue)[found->cvalue] = (header->nvalue)[0]; |
|
||||
(found->value)[(found->cvalue)++] = (header->value)[0]; |
|
||||
found->size += header->size; |
|
||||
(header->value)[0] = NULL; |
|
||||
delete(header); |
|
||||
} |
|
||||
|
|
||||
return found; |
|
||||
} |
|
||||
|
|
||||
// vim: set ts=4 sw=4: |
|
||||
@ -1,116 +0,0 @@ |
|||||
/** |
|
||||
* \file |
|
||||
* |
|
||||
* \author Georg Hopp |
|
||||
* |
|
||||
* \copyright |
|
||||
* Copyright (C) 2012 Georg Hopp |
|
||||
* |
|
||||
* This program is free software: you can redistribute it and/or modify |
|
||||
* it under the terms of the GNU General Public License as published by |
|
||||
* the Free Software Foundation, either version 3 of the License, or |
|
||||
* (at your option) any later version. |
|
||||
* |
|
||||
* This program is distributed in the hope that it will be useful, |
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
* GNU General Public License for more details. |
|
||||
* |
|
||||
* You should have received a copy of the GNU General Public License |
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
||||
*/ |
|
||||
|
|
||||
#include <stdlib.h> |
|
||||
#include <string.h> |
|
||||
#include <stdio.h> |
|
||||
#include <time.h> |
|
||||
#include <sys/types.h> |
|
||||
|
|
||||
#include "class.h" |
|
||||
#include "interface/class.h" |
|
||||
|
|
||||
#include "http/response.h" |
|
||||
#include "http/message.h" |
|
||||
#include "http/header.h" |
|
||||
|
|
||||
#include "utils/memory.h" |
|
||||
|
|
||||
|
|
||||
#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ |
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ |
|
||||
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ |
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" \ |
|
||||
"<head>" \ |
|
||||
"<title>My own little Web-App</title>" \ |
|
||||
"<style type=\"text/css\">" \ |
|
||||
"div#randval {" \ |
|
||||
"left: 200px;" \ |
|
||||
"top: 100px;" \ |
|
||||
"position: fixed;" \ |
|
||||
"background-color: white;" \ |
|
||||
"border: 1px solid black;" \ |
|
||||
"}" \ |
|
||||
"div.hide#randval {" \ |
|
||||
"top: -500px;" \ |
|
||||
"}" \ |
|
||||
".small {" \ |
|
||||
"font-size: small;" \ |
|
||||
"}" \ |
|
||||
"</style>" \ |
|
||||
"<script type=\"text/javascript\" src=\"/assets/js/jquery\"></script>" \ |
|
||||
"<script type=\"text/javascript\" src=\"/assets/js/serverval\"></script>" \ |
|
||||
"<script>" \ |
|
||||
"$(document).ready(function() {" \ |
|
||||
"var sval = new ServerVal(\"#randval\");" \ |
|
||||
"$(\"a\").click(function() {" \ |
|
||||
"sval.start();" \ |
|
||||
"});" \ |
|
||||
"});" \ |
|
||||
"</script>" \ |
|
||||
"</head>" \ |
|
||||
"<body>" |
|
||||
"<ul id=\"menu\">" \ |
|
||||
"<li>serverval</li>" \ |
|
||||
"</ul>" \ |
|
||||
"<div id=\"randval\" class=\"hide\">" \ |
|
||||
"<span class=\"small\">" \ |
|
||||
"Value created at: <br /><span></span><br>" \ |
|
||||
"Next value in: <span></span><br />" \ |
|
||||
"</span>" \ |
|
||||
"Value: <span></span>" \ |
|
||||
"</div>" \ |
|
||||
"<div id=\"main\">" \ |
|
||||
"<h1>Testpage</h1>" \ |
|
||||
"Welcome %s<br />" \ |
|
||||
"<img src=\"/image/\" />" \ |
|
||||
"</div>" \ |
|
||||
"<hr /><div id=\"msg\"></div>" \ |
|
||||
"</body>" \ |
|
||||
"</html>" |
|
||||
|
|
||||
HttpResponse |
|
||||
httpResponseMe(char * uname) |
|
||||
{ |
|
||||
HttpResponse response; |
|
||||
HttpMessage message; |
|
||||
|
|
||||
response = new(HttpResponse, "HTTP/1.1", 200, "OK"); |
|
||||
message = (HttpMessage)response; |
|
||||
|
|
||||
httpHeaderAdd(&(message->header), |
|
||||
new(HttpHeader, CSTRA("Content-Type"), CSTRA("text/html"))); |
|
||||
httpHeaderAdd(&(message->header), |
|
||||
new(HttpHeader, CSTRA("Set-Cookie"), CSTRA("name=Georg+Hopp"))); |
|
||||
httpHeaderAdd(&(message->header), |
|
||||
new(HttpHeader, CSTRA("Set-Cookie"), CSTRA("profession=coder"))); |
|
||||
|
|
||||
message->type = HTTP_MESSAGE_BUFFERED; |
|
||||
message->nbody = sizeof(RESP_DATA)-1-2+strlen(uname); //!< the two are the %s |
|
||||
message->body = malloc(message->nbody+1); |
|
||||
sprintf(message->body, RESP_DATA, uname); |
|
||||
//memcpy(message->body, RESP_DATA, sizeof(RESP_DATA)-1); |
|
||||
|
|
||||
return response; |
|
||||
} |
|
||||
|
|
||||
// vim: set ts=4 sw=4: |
|
||||
@ -0,0 +1,51 @@ |
|||||
|
/** |
||||
|
* \file |
||||
|
* |
||||
|
* \author Georg Hopp |
||||
|
* |
||||
|
* \copyright |
||||
|
* Copyright © 2012 Georg Hopp |
||||
|
* |
||||
|
* This program is free software: you can redistribute it and/or modify |
||||
|
* it under the terms of the GNU General Public License as published by |
||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||
|
* (at your option) any later version. |
||||
|
* |
||||
|
* This program is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
* GNU General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU General Public License |
||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <stdio.h> |
||||
|
#include <stdarg.h> |
||||
|
|
||||
|
#include "class.h" |
||||
|
#include "interface/hashable.h" |
||||
|
|
||||
|
const struct interface i_Hashable = { |
||||
|
"hashable", |
||||
|
2 |
||||
|
}; |
||||
|
|
||||
|
unsigned long |
||||
|
hashableGetHash(void * hashable) |
||||
|
{ |
||||
|
unsigned long ret; |
||||
|
|
||||
|
RETCALL(hashable, Hashable, getHash, ret); |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
hashableHandleDouble(void * hashable, void * new_hashable) |
||||
|
{ |
||||
|
CALL(hashable, Hashable, handleDouble, new_hashable); |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue