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,6 +5,14 @@
5 #define TRUE 1 5 #define TRUE 1
6 #define FALSE 0 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 #endif // __COMMONS_H__ 16 #endif // __COMMONS_H__
9 17
10 // vim: set ts=4 sw=4: 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,6 +61,8 @@ ssize_t httpParserParse(void *, Stream);
61 void httpParserHeader(HttpParser, const char *, const char *); 61 void httpParserHeader(HttpParser, const char *, const char *);
62 void httpParserNewMessage(HttpParser, const char *, const char * lend); 62 void httpParserNewMessage(HttpParser, const char *, const char * lend);
63 size_t httpParserBody(HttpParser, const char *, size_t); 63 size_t httpParserBody(HttpParser, const char *, size_t);
  64 +void httpParserRequestVars(HttpParser);
  65 +void httpParserPostVars(HttpParser);
64 66
65 #endif // __HTTP_PARSER_H__ 67 #endif // __HTTP_PARSER_H__
66 68
@@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
26 26
27 #include "class.h" 27 #include "class.h"
28 #include "http/message.h" 28 #include "http/message.h"
  29 +#include "hash.h"
29 30
30 #define N_HTTP_METHOD 8 31 #define N_HTTP_METHOD 8
31 32
@@ -36,6 +37,11 @@ CLASS(HttpRequest) { @@ -36,6 +37,11 @@ CLASS(HttpRequest) {
36 37
37 char * method; 38 char * method;
38 char * uri; 39 char * uri;
  40 + char * path;
  41 +
  42 + Hash get;
  43 + Hash post;
  44 + Hash cookies;
39 }; 45 };
40 46
41 int httpRequestHasValidMethod(HttpRequest); 47 int httpRequestHasValidMethod(HttpRequest);
@@ -11,7 +11,8 @@ HASH = hash.c \ @@ -11,7 +11,8 @@ HASH = hash.c \
11 hash/get.c \ 11 hash/get.c \
12 hash/delete.c \ 12 hash/delete.c \
13 hash/each.c \ 13 hash/each.c \
14 - interface/hashable.c 14 + interface/hashable.c \
  15 + hash_value.c
15 SERVER = server.c server/run.c server/close_conn.c server/poll.c \ 16 SERVER = server.c server/run.c server/close_conn.c server/poll.c \
16 server/handle_accept.c server/read.c server/write.c 17 server/handle_accept.c server/read.c server/write.c
17 LOGGER = logger.c logger/stderr.c logger/syslog.c 18 LOGGER = logger.c logger/stderr.c logger/syslog.c
@@ -42,7 +43,9 @@ PARSER = http/parser.c \ @@ -42,7 +43,9 @@ PARSER = http/parser.c \
42 http/parser/parse.c \ 43 http/parser/parse.c \
43 http/parser/new_message.c \ 44 http/parser/new_message.c \
44 http/parser/header.c \ 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 WRITER = http/writer.c \ 49 WRITER = http/writer.c \
47 http/writer/write.c 50 http/writer/write.c
48 WORKER = http/worker.c \ 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,11 +23,18 @@
23 #include <stdlib.h> 23 #include <stdlib.h>
24 24
25 #include "http/parser.h" 25 #include "http/parser.h"
  26 +#include "http/header.h"
26 #include "interface/class.h" 27 #include "interface/class.h"
27 #include "interface/http_intro.h" 28 #include "interface/http_intro.h"
28 #include "cbuf.h" 29 #include "cbuf.h"
29 #include "stream.h" 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 ssize_t 38 ssize_t
32 httpParserParse(void * _this, Stream st) 39 httpParserParse(void * _this, Stream st)
33 { 40 {
@@ -92,6 +99,7 @@ httpParserParse(void * _this, Stream st) @@ -92,6 +99,7 @@ httpParserParse(void * _this, Stream st)
92 this->ourLock = FALSE; 99 this->ourLock = FALSE;
93 return -1; 100 return -1;
94 } 101 }
  102 + httpParserRequestVars(this);
95 103
96 this->state = HTTP_MESSAGE_INTRO_DONE; 104 this->state = HTTP_MESSAGE_INTRO_DONE;
97 break; 105 break;
@@ -141,17 +149,34 @@ httpParserParse(void * _this, Stream st) @@ -141,17 +149,34 @@ httpParserParse(void * _this, Stream st)
141 break; 149 break;
142 150
143 case HTTP_MESSAGE_DONE: 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 break; 180 break;
156 181
157 default: 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,6 +56,10 @@ httpRequestCtor(void * _this, va_list * params)
56 this->uri[ulen] = 0; 56 this->uri[ulen] = 0;
57 memcpy(this->uri, uri, ulen); 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 return 0; 63 return 0;
60 } 64 }
61 65
@@ -65,6 +69,10 @@ httpRequestDtor(void * _this) @@ -65,6 +69,10 @@ httpRequestDtor(void * _this)
65 { 69 {
66 HttpRequest this = _this; 70 HttpRequest this = _this;
67 71
  72 + delete(this->get);
  73 + delete(this->post);
  74 + delete(this->cookies);
  75 +
68 FREE(this->uri); 76 FREE(this->uri);
69 FREE(this->method); 77 FREE(this->method);
70 78
@@ -38,6 +38,8 @@ @@ -38,6 +38,8 @@
38 #include "http/parser.h" 38 #include "http/parser.h"
39 #include "session.h" 39 #include "session.h"
40 #include "stream.h" 40 #include "stream.h"
  41 +#include "hash_value.h"
  42 +#include "hash.h"
41 43
42 #include "utils/memory.h" 44 #include "utils/memory.h"
43 #include "hash.h" 45 #include "hash.h"
@@ -94,21 +96,15 @@ httpWorkerProcess(HttpWorker this, Stream st) @@ -94,21 +96,15 @@ httpWorkerProcess(HttpWorker this, Stream st)
94 } 96 }
95 97
96 if (0 == strcmp("POST", request->method)) { 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 char buffer[200]; 100 char buffer[200];
102 size_t nbuf; 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 this->session = sessionAdd( 105 this->session = sessionAdd(
110 this->sroot, 106 this->sroot,
111 - new(Session, val, nval)); 107 + new(Session, username->value, username->nvalue));
112 nbuf = sprintf(buffer, "sid=%lu;Path=/", this->session->id); 108 nbuf = sprintf(buffer, "sid=%lu;Path=/", this->session->id);
113 109
114 response = (HttpMessage)httpResponseSession(this->session); 110 response = (HttpMessage)httpResponseSession(this->session);
@@ -120,18 +116,18 @@ httpWorkerProcess(HttpWorker this, Stream st) @@ -120,18 +116,18 @@ httpWorkerProcess(HttpWorker this, Stream st)
120 116
121 if (0 == strcmp("GET", request->method)) { 117 if (0 == strcmp("GET", request->method)) {
122 118
123 - if (0 == strcmp("/", request->uri)) { 119 + if (0 == strcmp("/", request->path)) {
124 response = httpWorkerGetAsset( 120 response = httpWorkerGetAsset(
125 request, 121 request,
126 "./assets/html/main.html", 122 "./assets/html/main.html",
127 CSTRA("text/html")); 123 CSTRA("text/html"));
128 } 124 }
129 125
130 - if (0 == strcmp("/sessinfo/", request->uri)) { 126 + if (0 == strcmp("/sessinfo/", request->path)) {
131 response = (HttpMessage)httpResponseSession(this->session); 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 if (NULL != this->session) { 131 if (NULL != this->session) {
136 response = (HttpMessage)httpResponseRandval( 132 response = (HttpMessage)httpResponseRandval(
137 this->val->timestamp, 133 this->val->timestamp,
@@ -141,42 +137,42 @@ httpWorkerProcess(HttpWorker this, Stream st) @@ -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 response = httpWorkerGetAsset( 141 response = httpWorkerGetAsset(
146 request, 142 request,
147 "./assets/image/waldschrat.jpg", 143 "./assets/image/waldschrat.jpg",
148 CSTRA("image/jpeg")); 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 response = httpWorkerGetAsset( 148 response = httpWorkerGetAsset(
153 request, 149 request,
154 "./assets/js/jquery-1.7.1.min.js", 150 "./assets/js/jquery-1.7.1.min.js",
155 CSTRA("text/javascript")); 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 response = httpWorkerGetAsset( 155 response = httpWorkerGetAsset(
160 request, 156 request,
161 "./assets/js/serverval.js", 157 "./assets/js/serverval.js",
162 CSTRA("text/javascript")); 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 response = httpWorkerGetAsset( 162 response = httpWorkerGetAsset(
167 request, 163 request,
168 "./assets/js/session.js", 164 "./assets/js/session.js",
169 CSTRA("text/javascript")); 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 response = httpWorkerGetAsset( 169 response = httpWorkerGetAsset(
174 request, 170 request,
175 "./assets/js/init.js", 171 "./assets/js/init.js",
176 CSTRA("text/javascript")); 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 response = httpWorkerGetAsset( 176 response = httpWorkerGetAsset(
181 request, 177 request,
182 "./assets/style/common.css", 178 "./assets/style/common.css",
@@ -29,7 +29,6 @@ @@ -29,7 +29,6 @@
29 #include "utils/signalHandling.h" 29 #include "utils/signalHandling.h"
30 30
31 #define POLLFD(ptr) ((struct pollfd *)(ptr)) 31 #define POLLFD(ptr) ((struct pollfd *)(ptr))
32 -#define SWAP(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))  
33 32
34 int 33 int
35 serverPoll(Server this) { 34 serverPoll(Server this) {
Please register or login to post a comment