Commit d0368bb28bd9ba88d8f016cb76af75510081caa3

Authored by Georg Hopp
1 parent 646d1e1c

GET and POST vars are now parsed when request ist parsed. COOKIE will follow. Wh…

…ile parsing the request line i also get pic the path from it.
... ... @@ -5,6 +5,14 @@
5 5 #define TRUE 1
6 6 #define FALSE 0
7 7
  8 +#define SWAP_FUN(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
  9 +
  10 +#define SWAP(type, a, b) do { \
  11 + type tmp = (a); \
  12 + (a) = (b); \
  13 + (b) = tmp; \
  14 +} while(0);
  15 +
8 16 #endif // __COMMONS_H__
9 17
10 18 // vim: set ts=4 sw=4:
... ...
  1 +#ifndef __HASH_VALUE_H__
  2 +#define __HASH_VALUE_H__
  3 +
  4 +#include <sys/types.h>
  5 +
  6 +#include "class.h"
  7 +
  8 +CLASS(HashValue) {
  9 + unsigned long hash;
  10 +
  11 + char * key;
  12 + void * value;
  13 +
  14 + size_t nkey;
  15 + size_t nvalue;
  16 +};
  17 +
  18 +#endif // __HASH_VALUE_H__
  19 +
  20 +// vim: set ts=4 sw=4:
... ...
  1 +#ifndef __HTTP_COOKIE_H__
  2 +#define __HTTP_COOKIE_H__
  3 +
  4 +#include <time.h>
  5 +#include <sys/types.h>
  6 +
  7 +#include "class.h"
  8 +
  9 +CLASS(HttpCookie) {
  10 + unsigned long hash;
  11 +
  12 + char * key;
  13 + char * value;
  14 + char * domain;
  15 + char * path;
  16 +
  17 + time_t expires;
  18 + time_t max_age;
  19 +
  20 + size_t nkey;
  21 + size_t nvalue;
  22 +};
  23 +
  24 +char * httpCookieToString(HttpCookie);
  25 +HttpCookie httpStringToCookie(const char *);
  26 +
  27 +#endif // __HTTP_COOKIE_H__
  28 +
  29 +// vim: set ts=4 sw=4:
... ...
... ... @@ -61,6 +61,8 @@ ssize_t httpParserParse(void *, Stream);
61 61 void httpParserHeader(HttpParser, const char *, const char *);
62 62 void httpParserNewMessage(HttpParser, const char *, const char * lend);
63 63 size_t httpParserBody(HttpParser, const char *, size_t);
  64 +void httpParserRequestVars(HttpParser);
  65 +void httpParserPostVars(HttpParser);
64 66
65 67 #endif // __HTTP_PARSER_H__
66 68
... ...
... ... @@ -26,6 +26,7 @@
26 26
27 27 #include "class.h"
28 28 #include "http/message.h"
  29 +#include "hash.h"
29 30
30 31 #define N_HTTP_METHOD 8
31 32
... ... @@ -36,6 +37,11 @@ CLASS(HttpRequest) {
36 37
37 38 char * method;
38 39 char * uri;
  40 + char * path;
  41 +
  42 + Hash get;
  43 + Hash post;
  44 + Hash cookies;
39 45 };
40 46
41 47 int httpRequestHasValidMethod(HttpRequest);
... ...
... ... @@ -11,7 +11,8 @@ HASH = hash.c \
11 11 hash/get.c \
12 12 hash/delete.c \
13 13 hash/each.c \
14   - interface/hashable.c
  14 + interface/hashable.c \
  15 + hash_value.c
15 16 SERVER = server.c server/run.c server/close_conn.c server/poll.c \
16 17 server/handle_accept.c server/read.c server/write.c
17 18 LOGGER = logger.c logger/stderr.c logger/syslog.c
... ... @@ -42,7 +43,9 @@ PARSER = http/parser.c \
42 43 http/parser/parse.c \
43 44 http/parser/new_message.c \
44 45 http/parser/header.c \
45   - http/parser/body.c
  46 + http/parser/body.c \
  47 + http/parser/request_vars.c \
  48 + http/parser/post_vars.c
46 49 WRITER = http/writer.c \
47 50 http/writer/write.c
48 51 WORKER = http/worker.c \
... ...
  1 +#include <stdarg.h>
  2 +#include <stdlib.h>
  3 +#include <string.h>
  4 +#include <sys/types.h>
  5 +
  6 +#include "hash_value.h"
  7 +#include "utils/hash.h"
  8 +#include "utils/memory.h"
  9 +#include "commons.h"
  10 +#include "interface/class.h"
  11 +#include "interface/hashable.h"
  12 +
  13 +static
  14 +int
  15 +hashValueCtor(void * _this, va_list * params)
  16 +{
  17 + HashValue this = _this;
  18 + char * key = va_arg(* params, char*);
  19 + void * value;
  20 +
  21 + this->nkey = va_arg(* params, size_t);
  22 + value = va_arg(* params, void*);
  23 + this->nvalue = va_arg(* params, size_t);
  24 +
  25 + this->key = malloc(this->nkey + 1);
  26 + this->key[this->nkey] = 0;
  27 + memcpy(this->key, key, this->nkey);
  28 +
  29 + this->hash = sdbm((unsigned char *)this->key, this->nkey);
  30 +
  31 + if (NULL != value) {
  32 + this->value = malloc(this->nvalue + 1);
  33 + ((char*)this->value)[this->nvalue] = 0;
  34 + memcpy(this->value, value, this->nvalue);
  35 + }
  36 +
  37 + return 0;
  38 +}
  39 +
  40 +static
  41 +void
  42 +hashValueDtor(void * _this)
  43 +{
  44 + HashValue this = _this;
  45 +
  46 + FREE(this->key);
  47 + FREE(this->value);
  48 +}
  49 +
  50 +static
  51 +unsigned long
  52 +hashValueGetHash(void * _this)
  53 +{
  54 + HashValue this = _this;
  55 +
  56 + return this->hash;
  57 +}
  58 +
  59 +static
  60 +void
  61 +hashValueHandleDouble(void * _this, void * _double)
  62 +{
  63 + HashValue this = _this;
  64 + HashValue doub = _double;
  65 + void * tmp_value;
  66 + size_t tmp_nvalue;
  67 +
  68 + /**
  69 + * here we swap the internal data of both objects,
  70 + * effectively overwriting the old entry. We need not
  71 + * to free anything here as _double will be deleted
  72 + * afterwards anyway (\see hash/add.c).
  73 + */
  74 + tmp_value = this->value;
  75 + this->value = doub->value;
  76 + doub->value = tmp_value;
  77 +
  78 + tmp_nvalue = this->nvalue;
  79 + this->nvalue = doub->nvalue;
  80 + doub->nvalue = tmp_nvalue;
  81 +}
  82 +
  83 +INIT_IFACE(Class, hashValueCtor, hashValueDtor, NULL);
  84 +INIT_IFACE(Hashable, hashValueGetHash, hashValueHandleDouble);
  85 +CREATE_CLASS(HashValue, NULL, IFACE(Class), IFACE(Hashable));
  86 +
  87 +// vim: set ts=4 sw=4:
... ...
  1 +#include <stdlib.h>
  2 +#include <string.h>
  3 +#include <stdarg.h>
  4 +#include <sys/types.h>
  5 +
  6 +#include "cookie.h"
  7 +#include "interface/class.h"
  8 +#include "interface/hashable"
  9 +
  10 +#include "utils/hash.h"
  11 +#include "utils/memory.h"
  12 +#include "commons.h"
  13 +
  14 +
  15 +static
  16 +int
  17 +httpCookieCtor(void * _this, va_list * params)
  18 +{
  19 + HttpCookie this = _this;
  20 + char * key = va_arg(* params, char*);
  21 + char * value;
  22 +
  23 + this->nkey = va_arg(* params, size_t);
  24 + value = va_arg(* params, char*);
  25 + this->nvalue = va_arg(* params, size_t);
  26 +
  27 + this->key = malloc(this->nkey + 1);
  28 + this->key[this->nkey] = 0;
  29 + memcpy(this->key, key, this->nkey);
  30 +
  31 + this->value = malloc(this->nvalue + 1);
  32 + this->value[this->nvalue] = 0;
  33 + memcpy(this->value, value, this->nvalue);
  34 +
  35 + this->hash = sdbm((unsigned char *)key, nkey);
  36 +
  37 + return 0;
  38 +}
  39 +
  40 +static
  41 +void
  42 +httpCookieDtor(void * _this, va_list * params)
  43 +{
  44 + HttpCookie this = _this;
  45 +
  46 + FREE(this->key);
  47 + FREE(this->value);
  48 + FREE(this->domain);
  49 + FREE(this->path);
  50 +}
  51 +
  52 +static
  53 +unsigned long
  54 +httpCookieGetHash(void * _this)
  55 +{
  56 + HttpCookie this = _this;
  57 +
  58 + return this->hash;
  59 +}
  60 +
  61 +static
  62 +void
  63 +httpCookieHandleDouble(void * _this, void * _double)
  64 +{
  65 + HttpCookie this = _this;
  66 + HttpCookie doub = _double;
  67 +
  68 + SWAP(char*, this->key, doub->key);
  69 + SWAP(char*, this->value, doub->value);
  70 + SWAP(char*, this->domain, doub->domain);
  71 + SWAP(char*, this->path, doub->path);
  72 +
  73 + SWAP(char*, this->nkey, doub->nkey);
  74 + SWAP(char*, this->nvalue, doub->nvalue);
  75 +}
  76 +
  77 +
  78 +INIT_IFACE(Class, httpCookieCtor, httpCookieDtor, NULL);
  79 +INIT_IFACE(Hashable, httpCookieGetHash, httpCookieHandleDouble);
  80 +CREATE_CLASS(HttpCookie, NULL, IFACE(Class), IFACE(Hashable));
  81 +
  82 +// vim: set ts=4 sw=4:
... ...
... ... @@ -23,11 +23,18 @@
23 23 #include <stdlib.h>
24 24
25 25 #include "http/parser.h"
  26 +#include "http/header.h"
26 27 #include "interface/class.h"
27 28 #include "interface/http_intro.h"
28 29 #include "cbuf.h"
29 30 #include "stream.h"
30 31
  32 +#include "utils/memory.h"
  33 +#include "commons.h"
  34 +
  35 +#define MIN(a,b) ((a)<(b)? (a) : (b))
  36 +
  37 +
31 38 ssize_t
32 39 httpParserParse(void * _this, Stream st)
33 40 {
... ... @@ -92,6 +99,7 @@ httpParserParse(void * _this, Stream st)
92 99 this->ourLock = FALSE;
93 100 return -1;
94 101 }
  102 + httpParserRequestVars(this);
95 103
96 104 this->state = HTTP_MESSAGE_INTRO_DONE;
97 105 break;
... ... @@ -141,17 +149,34 @@ httpParserParse(void * _this, Stream st)
141 149 break;
142 150
143 151 case HTTP_MESSAGE_DONE:
144   - /**
145   - * enqueue current request
146   - */
147   - this->queue->msgs[(this->queue->nmsgs)++] = this->current;
148   - this->current = NULL;
  152 + {
  153 + HttpHeader enc = hashGet(
  154 + this->current->header,
  155 + CSTRA("content-type"));
  156 +
  157 + /**
  158 + * do we have form data??
  159 + */
  160 + if (NULL != enc && 0 == strncasecmp(
  161 + "application/x-www-form-urlencoded",
  162 + enc->value[0],
  163 + MIN(sizeof("application/x-www-form-urlencoded")-1,
  164 + enc->nvalue[0]))) {
  165 + //!> then parse them...
  166 + httpParserPostVars(this);
  167 + }
149 168
150   - /**
151   - * prepare for next request
152   - */
153   - this->state = HTTP_MESSAGE_GARBAGE;
  169 + /**
  170 + * enqueue current request
  171 + */
  172 + this->queue->msgs[(this->queue->nmsgs)++] = this->current;
  173 + this->current = NULL;
154 174
  175 + /**
  176 + * prepare for next request
  177 + */
  178 + this->state = HTTP_MESSAGE_GARBAGE;
  179 + }
155 180 break;
156 181
157 182 default:
... ...
  1 +#include <string.h>
  2 +#include <sys/types.h>
  3 +
  4 +#include "http/parser.h"
  5 +#include "http/request.h"
  6 +#include "hash_value.h"
  7 +#include "hash.h"
  8 +#include "interface/class.h"
  9 +
  10 +/**
  11 + * \todo this is very similar to other pair parsing
  12 + * things... key1=val1<delim>key2=val2<delim>...keyn=valn
  13 + * Generalize this!!!!
  14 + */
  15 +void
  16 +httpParserPostVars(HttpParser this)
  17 +{
  18 + HttpRequest request = (HttpRequest)this->current;
  19 + char * pair = this->current->body;
  20 + size_t togo = this->current->nbody;
  21 +
  22 + while(NULL != pair && 0 < togo) {
  23 + char * key = pair;
  24 + char * eqsign = memchr(key, '=', togo);
  25 + char * value;
  26 + size_t nvalue;
  27 +
  28 + if (NULL == eqsign) {
  29 + return;
  30 + }
  31 +
  32 + togo -= (eqsign - key);
  33 + pair = memchr(eqsign, '&', togo);
  34 +
  35 + if (NULL == pair) {
  36 + pair = &(this->current->body[this->current->nbody]);
  37 + }
  38 +
  39 + nvalue = pair-eqsign-1;
  40 + value = (0 != nvalue)? eqsign+1 : NULL;
  41 +
  42 + hashAdd(request->post,
  43 + new(HashValue, key, eqsign-key, value, nvalue));
  44 +
  45 + togo -= (pair - eqsign);
  46 + }
  47 +}
  48 +
  49 +// vim: set ts=4 sw=4:
... ...
  1 +#include <stdlib.h>
  2 +#include <string.h>
  3 +#include <sys/types.h>
  4 +
  5 +#include "http/parser.h"
  6 +#include "http/request.h"
  7 +#include "hash_value.h"
  8 +#include "hash.h"
  9 +#include "interface/class.h"
  10 +
  11 +void
  12 +httpParserRequestVars(HttpParser this)
  13 +{
  14 + HttpRequest request = (HttpRequest)this->current;
  15 + char * delim = strchr(request->uri, '?');
  16 +
  17 + if (NULL == delim) {
  18 + delim = request->uri + strlen(request->uri);
  19 + }
  20 +
  21 + request->path = malloc(delim - request->uri + 1);
  22 + request->path[delim - request->uri + 1] = 0;
  23 + memcpy(request->path, request->uri, delim - request->uri + 1);
  24 +
  25 + while(NULL != delim && 0 != *delim) {
  26 + char * key = delim + 1;
  27 + char * eqsign = strchr(key, '=');
  28 + char * value;
  29 + size_t nvalue;
  30 +
  31 + if (NULL == eqsign) {
  32 + return;
  33 + }
  34 +
  35 + delim = strchr(eqsign, '&');
  36 +
  37 + if (NULL == delim) {
  38 + delim = key + strlen(key);
  39 + }
  40 +
  41 + nvalue = delim-eqsign-1;
  42 + value = (0 != nvalue)? eqsign+1 : NULL;
  43 +
  44 + hashAdd(request->get,
  45 + new(HashValue, key, eqsign-key, value, nvalue));
  46 + }
  47 +}
  48 +
  49 +// vim: set ts=4 sw=4:
... ...
... ... @@ -56,6 +56,10 @@ httpRequestCtor(void * _this, va_list * params)
56 56 this->uri[ulen] = 0;
57 57 memcpy(this->uri, uri, ulen);
58 58
  59 + this->get = new(Hash);
  60 + this->post = new(Hash);
  61 + this->cookies = new(Hash);
  62 +
59 63 return 0;
60 64 }
61 65
... ... @@ -65,6 +69,10 @@ httpRequestDtor(void * _this)
65 69 {
66 70 HttpRequest this = _this;
67 71
  72 + delete(this->get);
  73 + delete(this->post);
  74 + delete(this->cookies);
  75 +
68 76 FREE(this->uri);
69 77 FREE(this->method);
70 78
... ...
... ... @@ -38,6 +38,8 @@
38 38 #include "http/parser.h"
39 39 #include "session.h"
40 40 #include "stream.h"
  41 +#include "hash_value.h"
  42 +#include "hash.h"
41 43
42 44 #include "utils/memory.h"
43 45 #include "hash.h"
... ... @@ -94,21 +96,15 @@ httpWorkerProcess(HttpWorker this, Stream st)
94 96 }
95 97
96 98 if (0 == strcmp("POST", request->method)) {
97   - if (0 == strcmp("/login/", request->uri)) {
98   - char * delim = memchr(rmessage->body, '=', rmessage->nbody);
99   - char * val;
100   - size_t nkey, nval;
  99 + if (0 == strcmp("/login/", request->path)) {
101 100 char buffer[200];
102 101 size_t nbuf;
103 102
104   - nkey = delim - rmessage->body - 1;
105   - *delim = 0;
106   - val = delim + 1;
107   - nval = rmessage->nbody - (val - rmessage->body);
  103 + HashValue username = hashGet(request->post, CSTRA("username"));
108 104
109 105 this->session = sessionAdd(
110 106 this->sroot,
111   - new(Session, val, nval));
  107 + new(Session, username->value, username->nvalue));
112 108 nbuf = sprintf(buffer, "sid=%lu;Path=/", this->session->id);
113 109
114 110 response = (HttpMessage)httpResponseSession(this->session);
... ... @@ -120,18 +116,18 @@ httpWorkerProcess(HttpWorker this, Stream st)
120 116
121 117 if (0 == strcmp("GET", request->method)) {
122 118
123   - if (0 == strcmp("/", request->uri)) {
  119 + if (0 == strcmp("/", request->path)) {
124 120 response = httpWorkerGetAsset(
125 121 request,
126 122 "./assets/html/main.html",
127 123 CSTRA("text/html"));
128 124 }
129 125
130   - if (0 == strcmp("/sessinfo/", request->uri)) {
  126 + if (0 == strcmp("/sessinfo/", request->path)) {
131 127 response = (HttpMessage)httpResponseSession(this->session);
132 128 }
133 129
134   - if (0 == strcmp("/randval/", request->uri)) {
  130 + if (0 == strcmp("/randval/", request->path)) {
135 131 if (NULL != this->session) {
136 132 response = (HttpMessage)httpResponseRandval(
137 133 this->val->timestamp,
... ... @@ -141,42 +137,42 @@ httpWorkerProcess(HttpWorker this, Stream st)
141 137 }
142 138 }
143 139
144   - if (0 == strcmp("/image/me", request->uri)) {
  140 + if (0 == strcmp("/image/me", request->path)) {
145 141 response = httpWorkerGetAsset(
146 142 request,
147 143 "./assets/image/waldschrat.jpg",
148 144 CSTRA("image/jpeg"));
149 145 }
150 146
151   - if (0 == strcmp("/assets/js/jquery", request->uri)) {
  147 + if (0 == strcmp("/assets/js/jquery", request->path)) {
152 148 response = httpWorkerGetAsset(
153 149 request,
154 150 "./assets/js/jquery-1.7.1.min.js",
155 151 CSTRA("text/javascript"));
156 152 }
157 153
158   - if (0 == strcmp("/assets/js/serverval", request->uri)) {
  154 + if (0 == strcmp("/assets/js/serverval", request->path)) {
159 155 response = httpWorkerGetAsset(
160 156 request,
161 157 "./assets/js/serverval.js",
162 158 CSTRA("text/javascript"));
163 159 }
164 160
165   - if (0 == strcmp("/assets/js/session", request->uri)) {
  161 + if (0 == strcmp("/assets/js/session", request->path)) {
166 162 response = httpWorkerGetAsset(
167 163 request,
168 164 "./assets/js/session.js",
169 165 CSTRA("text/javascript"));
170 166 }
171 167
172   - if (0 == strcmp("/assets/js/init", request->uri)) {
  168 + if (0 == strcmp("/assets/js/init", request->path)) {
173 169 response = httpWorkerGetAsset(
174 170 request,
175 171 "./assets/js/init.js",
176 172 CSTRA("text/javascript"));
177 173 }
178 174
179   - if (0 == strcmp("/assets/style/common", request->uri)) {
  175 + if (0 == strcmp("/assets/style/common", request->path)) {
180 176 response = httpWorkerGetAsset(
181 177 request,
182 178 "./assets/style/common.css",
... ...
... ... @@ -29,7 +29,6 @@
29 29 #include "utils/signalHandling.h"
30 30
31 31 #define POLLFD(ptr) ((struct pollfd *)(ptr))
32   -#define SWAP(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
33 32
34 33 int
35 34 serverPoll(Server this) {
... ...
Please register or login to post a comment