Browse Source

GET and POST vars are now parsed when request ist parsed. COOKIE will follow. While parsing the request line i also get pic the path from it.

master
Georg Hopp 14 years ago
parent
commit
d0368bb28b
  1. 8
      include/commons.h
  2. 20
      include/hash_value.h
  3. 29
      include/http/cookie.h
  4. 2
      include/http/parser.h
  5. 6
      include/http/request.h
  6. 7
      src/Makefile.am
  7. 87
      src/hash_value.c
  8. 82
      src/http/cookie.c
  9. 43
      src/http/parser/parse.c
  10. 49
      src/http/parser/post_vars.c
  11. 49
      src/http/parser/request_vars.c
  12. 8
      src/http/request.c
  13. 32
      src/http/worker/process.c
  14. 1
      src/server/poll.c

8
include/commons.h

@ -5,6 +5,14 @@
#define TRUE 1
#define FALSE 0
#define SWAP_FUN(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define SWAP(type, a, b) do { \
type tmp = (a); \
(a) = (b); \
(b) = tmp; \
} while(0);
#endif // __COMMONS_H__
// vim: set ts=4 sw=4:

20
include/hash_value.h

@ -0,0 +1,20 @@
#ifndef __HASH_VALUE_H__
#define __HASH_VALUE_H__
#include <sys/types.h>
#include "class.h"
CLASS(HashValue) {
unsigned long hash;
char * key;
void * value;
size_t nkey;
size_t nvalue;
};
#endif // __HASH_VALUE_H__
// vim: set ts=4 sw=4:

29
include/http/cookie.h

@ -0,0 +1,29 @@
#ifndef __HTTP_COOKIE_H__
#define __HTTP_COOKIE_H__
#include <time.h>
#include <sys/types.h>
#include "class.h"
CLASS(HttpCookie) {
unsigned long hash;
char * key;
char * value;
char * domain;
char * path;
time_t expires;
time_t max_age;
size_t nkey;
size_t nvalue;
};
char * httpCookieToString(HttpCookie);
HttpCookie httpStringToCookie(const char *);
#endif // __HTTP_COOKIE_H__
// vim: set ts=4 sw=4:

2
include/http/parser.h

@ -61,6 +61,8 @@ ssize_t httpParserParse(void *, Stream);
void httpParserHeader(HttpParser, const char *, const char *);
void httpParserNewMessage(HttpParser, const char *, const char * lend);
size_t httpParserBody(HttpParser, const char *, size_t);
void httpParserRequestVars(HttpParser);
void httpParserPostVars(HttpParser);
#endif // __HTTP_PARSER_H__

6
include/http/request.h

@ -26,6 +26,7 @@
#include "class.h"
#include "http/message.h"
#include "hash.h"
#define N_HTTP_METHOD 8
@ -36,6 +37,11 @@ CLASS(HttpRequest) {
char * method;
char * uri;
char * path;
Hash get;
Hash post;
Hash cookies;
};
int httpRequestHasValidMethod(HttpRequest);

7
src/Makefile.am

@ -11,7 +11,8 @@ HASH = hash.c \
hash/get.c \
hash/delete.c \
hash/each.c \
interface/hashable.c
interface/hashable.c \
hash_value.c
SERVER = server.c server/run.c server/close_conn.c server/poll.c \
server/handle_accept.c server/read.c server/write.c
LOGGER = logger.c logger/stderr.c logger/syslog.c
@ -42,7 +43,9 @@ PARSER = http/parser.c \
http/parser/parse.c \
http/parser/new_message.c \
http/parser/header.c \
http/parser/body.c
http/parser/body.c \
http/parser/request_vars.c \
http/parser/post_vars.c
WRITER = http/writer.c \
http/writer/write.c
WORKER = http/worker.c \

87
src/hash_value.c

@ -0,0 +1,87 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "hash_value.h"
#include "utils/hash.h"
#include "utils/memory.h"
#include "commons.h"
#include "interface/class.h"
#include "interface/hashable.h"
static
int
hashValueCtor(void * _this, va_list * params)
{
HashValue this = _this;
char * key = va_arg(* params, char*);
void * value;
this->nkey = va_arg(* params, size_t);
value = va_arg(* params, void*);
this->nvalue = va_arg(* params, size_t);
this->key = malloc(this->nkey + 1);
this->key[this->nkey] = 0;
memcpy(this->key, key, this->nkey);
this->hash = sdbm((unsigned char *)this->key, this->nkey);
if (NULL != value) {
this->value = malloc(this->nvalue + 1);
((char*)this->value)[this->nvalue] = 0;
memcpy(this->value, value, this->nvalue);
}
return 0;
}
static
void
hashValueDtor(void * _this)
{
HashValue this = _this;
FREE(this->key);
FREE(this->value);
}
static
unsigned long
hashValueGetHash(void * _this)
{
HashValue this = _this;
return this->hash;
}
static
void
hashValueHandleDouble(void * _this, void * _double)
{
HashValue this = _this;
HashValue doub = _double;
void * tmp_value;
size_t tmp_nvalue;
/**
* here we swap the internal data of both objects,
* effectively overwriting the old entry. We need not
* to free anything here as _double will be deleted
* afterwards anyway (\see hash/add.c).
*/
tmp_value = this->value;
this->value = doub->value;
doub->value = tmp_value;
tmp_nvalue = this->nvalue;
this->nvalue = doub->nvalue;
doub->nvalue = tmp_nvalue;
}
INIT_IFACE(Class, hashValueCtor, hashValueDtor, NULL);
INIT_IFACE(Hashable, hashValueGetHash, hashValueHandleDouble);
CREATE_CLASS(HashValue, NULL, IFACE(Class), IFACE(Hashable));
// vim: set ts=4 sw=4:

82
src/http/cookie.c

@ -0,0 +1,82 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include "cookie.h"
#include "interface/class.h"
#include "interface/hashable"
#include "utils/hash.h"
#include "utils/memory.h"
#include "commons.h"
static
int
httpCookieCtor(void * _this, va_list * params)
{
HttpCookie this = _this;
char * key = va_arg(* params, char*);
char * value;
this->nkey = va_arg(* params, size_t);
value = va_arg(* params, char*);
this->nvalue = va_arg(* params, size_t);
this->key = malloc(this->nkey + 1);
this->key[this->nkey] = 0;
memcpy(this->key, key, this->nkey);
this->value = malloc(this->nvalue + 1);
this->value[this->nvalue] = 0;
memcpy(this->value, value, this->nvalue);
this->hash = sdbm((unsigned char *)key, nkey);
return 0;
}
static
void
httpCookieDtor(void * _this, va_list * params)
{
HttpCookie this = _this;
FREE(this->key);
FREE(this->value);
FREE(this->domain);
FREE(this->path);
}
static
unsigned long
httpCookieGetHash(void * _this)
{
HttpCookie this = _this;
return this->hash;
}
static
void
httpCookieHandleDouble(void * _this, void * _double)
{
HttpCookie this = _this;
HttpCookie doub = _double;
SWAP(char*, this->key, doub->key);
SWAP(char*, this->value, doub->value);
SWAP(char*, this->domain, doub->domain);
SWAP(char*, this->path, doub->path);
SWAP(char*, this->nkey, doub->nkey);
SWAP(char*, this->nvalue, doub->nvalue);
}
INIT_IFACE(Class, httpCookieCtor, httpCookieDtor, NULL);
INIT_IFACE(Hashable, httpCookieGetHash, httpCookieHandleDouble);
CREATE_CLASS(HttpCookie, NULL, IFACE(Class), IFACE(Hashable));
// vim: set ts=4 sw=4:

43
src/http/parser/parse.c

@ -23,11 +23,18 @@
#include <stdlib.h>
#include "http/parser.h"
#include "http/header.h"
#include "interface/class.h"
#include "interface/http_intro.h"
#include "cbuf.h"
#include "stream.h"
#include "utils/memory.h"
#include "commons.h"
#define MIN(a,b) ((a)<(b)? (a) : (b))
ssize_t
httpParserParse(void * _this, Stream st)
{
@ -92,6 +99,7 @@ httpParserParse(void * _this, Stream st)
this->ourLock = FALSE;
return -1;
}
httpParserRequestVars(this);
this->state = HTTP_MESSAGE_INTRO_DONE;
break;
@ -141,17 +149,34 @@ httpParserParse(void * _this, Stream st)
break;
case HTTP_MESSAGE_DONE:
/**
* enqueue current request
*/
this->queue->msgs[(this->queue->nmsgs)++] = this->current;
this->current = NULL;
{
HttpHeader enc = hashGet(
this->current->header,
CSTRA("content-type"));
/**
* do we have form data??
*/
if (NULL != enc && 0 == strncasecmp(
"application/x-www-form-urlencoded",
enc->value[0],
MIN(sizeof("application/x-www-form-urlencoded")-1,
enc->nvalue[0]))) {
//!> then parse them...
httpParserPostVars(this);
}
/**
* prepare for next request
*/
this->state = HTTP_MESSAGE_GARBAGE;
/**
* enqueue current request
*/
this->queue->msgs[(this->queue->nmsgs)++] = this->current;
this->current = NULL;
/**
* prepare for next request
*/
this->state = HTTP_MESSAGE_GARBAGE;
}
break;
default:

49
src/http/parser/post_vars.c

@ -0,0 +1,49 @@
#include <string.h>
#include <sys/types.h>
#include "http/parser.h"
#include "http/request.h"
#include "hash_value.h"
#include "hash.h"
#include "interface/class.h"
/**
* \todo this is very similar to other pair parsing
* things... key1=val1<delim>key2=val2<delim>...keyn=valn
* Generalize this!!!!
*/
void
httpParserPostVars(HttpParser this)
{
HttpRequest request = (HttpRequest)this->current;
char * pair = this->current->body;
size_t togo = this->current->nbody;
while(NULL != pair && 0 < togo) {
char * key = pair;
char * eqsign = memchr(key, '=', togo);
char * value;
size_t nvalue;
if (NULL == eqsign) {
return;
}
togo -= (eqsign - key);
pair = memchr(eqsign, '&', togo);
if (NULL == pair) {
pair = &(this->current->body[this->current->nbody]);
}
nvalue = pair-eqsign-1;
value = (0 != nvalue)? eqsign+1 : NULL;
hashAdd(request->post,
new(HashValue, key, eqsign-key, value, nvalue));
togo -= (pair - eqsign);
}
}
// vim: set ts=4 sw=4:

49
src/http/parser/request_vars.c

@ -0,0 +1,49 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "http/parser.h"
#include "http/request.h"
#include "hash_value.h"
#include "hash.h"
#include "interface/class.h"
void
httpParserRequestVars(HttpParser this)
{
HttpRequest request = (HttpRequest)this->current;
char * delim = strchr(request->uri, '?');
if (NULL == delim) {
delim = request->uri + strlen(request->uri);
}
request->path = malloc(delim - request->uri + 1);
request->path[delim - request->uri + 1] = 0;
memcpy(request->path, request->uri, delim - request->uri + 1);
while(NULL != delim && 0 != *delim) {
char * key = delim + 1;
char * eqsign = strchr(key, '=');
char * value;
size_t nvalue;
if (NULL == eqsign) {
return;
}
delim = strchr(eqsign, '&');
if (NULL == delim) {
delim = key + strlen(key);
}
nvalue = delim-eqsign-1;
value = (0 != nvalue)? eqsign+1 : NULL;
hashAdd(request->get,
new(HashValue, key, eqsign-key, value, nvalue));
}
}
// vim: set ts=4 sw=4:

8
src/http/request.c

@ -56,6 +56,10 @@ httpRequestCtor(void * _this, va_list * params)
this->uri[ulen] = 0;
memcpy(this->uri, uri, ulen);
this->get = new(Hash);
this->post = new(Hash);
this->cookies = new(Hash);
return 0;
}
@ -65,6 +69,10 @@ httpRequestDtor(void * _this)
{
HttpRequest this = _this;
delete(this->get);
delete(this->post);
delete(this->cookies);
FREE(this->uri);
FREE(this->method);

32
src/http/worker/process.c

@ -38,6 +38,8 @@
#include "http/parser.h"
#include "session.h"
#include "stream.h"
#include "hash_value.h"
#include "hash.h"
#include "utils/memory.h"
#include "hash.h"
@ -94,21 +96,15 @@ httpWorkerProcess(HttpWorker this, Stream st)
}
if (0 == strcmp("POST", request->method)) {
if (0 == strcmp("/login/", request->uri)) {
char * delim = memchr(rmessage->body, '=', rmessage->nbody);
char * val;
size_t nkey, nval;
if (0 == strcmp("/login/", request->path)) {
char buffer[200];
size_t nbuf;
nkey = delim - rmessage->body - 1;
*delim = 0;
val = delim + 1;
nval = rmessage->nbody - (val - rmessage->body);
HashValue username = hashGet(request->post, CSTRA("username"));
this->session = sessionAdd(
this->sroot,
new(Session, val, nval));
new(Session, username->value, username->nvalue));
nbuf = sprintf(buffer, "sid=%lu;Path=/", this->session->id);
response = (HttpMessage)httpResponseSession(this->session);
@ -120,18 +116,18 @@ httpWorkerProcess(HttpWorker this, Stream st)
if (0 == strcmp("GET", request->method)) {
if (0 == strcmp("/", request->uri)) {
if (0 == strcmp("/", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/html/main.html",
CSTRA("text/html"));
}
if (0 == strcmp("/sessinfo/", request->uri)) {
if (0 == strcmp("/sessinfo/", request->path)) {
response = (HttpMessage)httpResponseSession(this->session);
}
if (0 == strcmp("/randval/", request->uri)) {
if (0 == strcmp("/randval/", request->path)) {
if (NULL != this->session) {
response = (HttpMessage)httpResponseRandval(
this->val->timestamp,
@ -141,42 +137,42 @@ httpWorkerProcess(HttpWorker this, Stream st)
}
}
if (0 == strcmp("/image/me", request->uri)) {
if (0 == strcmp("/image/me", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/image/waldschrat.jpg",
CSTRA("image/jpeg"));
}
if (0 == strcmp("/assets/js/jquery", request->uri)) {
if (0 == strcmp("/assets/js/jquery", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/js/jquery-1.7.1.min.js",
CSTRA("text/javascript"));
}
if (0 == strcmp("/assets/js/serverval", request->uri)) {
if (0 == strcmp("/assets/js/serverval", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/js/serverval.js",
CSTRA("text/javascript"));
}
if (0 == strcmp("/assets/js/session", request->uri)) {
if (0 == strcmp("/assets/js/session", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/js/session.js",
CSTRA("text/javascript"));
}
if (0 == strcmp("/assets/js/init", request->uri)) {
if (0 == strcmp("/assets/js/init", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/js/init.js",
CSTRA("text/javascript"));
}
if (0 == strcmp("/assets/style/common", request->uri)) {
if (0 == strcmp("/assets/style/common", request->path)) {
response = httpWorkerGetAsset(
request,
"./assets/style/common.css",

1
src/server/poll.c

@ -29,7 +29,6 @@
#include "utils/signalHandling.h"
#define POLLFD(ptr) ((struct pollfd *)(ptr))
#define SWAP(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
int
serverPoll(Server this) {

Loading…
Cancel
Save