refactored strongswan manager

removed buggy request parsing code, use ClearSilvers CGI kit instead
fixed CHILD_SA listing in manager (needs better design)
using secure XML communication through unix sockets
removed images with questionable (non-GPL) license
This commit is contained in:
Martin Willi
2007-09-26 14:02:21 +00:00
parent a9522e1600
commit c295d0eb4b
41 changed files with 722 additions and 1219 deletions
+2 -4
View File
@@ -24,7 +24,6 @@
#define CONTROLLER_H_
#include "request.h"
#include "response.h"
#include "context.h"
typedef struct controller_t controller_t;
@@ -35,7 +34,7 @@ typedef struct controller_t controller_t;
* @param request http request
* @param response http response
*/
typedef void *(*controller_handler_t)(controller_t *this, request_t *request, response_t *response);
typedef void *(*controller_handler_t)(controller_t *this, request_t *request);
/**
* @brief Constructor function for a controller
@@ -66,7 +65,6 @@ struct controller_t {
* parameter not found in the request URL is set to NULL.
*
* @param request HTTP request
* @param response HTTP response
* @param p1 first parameter
* @param p2 second parameter
* @param p3 third parameter
@@ -74,7 +72,7 @@ struct controller_t {
* @param p5 fifth parameter
* @return
*/
void (*handle)(controller_t *this, request_t *request, response_t *response,
void (*handle)(controller_t *this, request_t *request,
char *a1, char *a2, char *a3, char *a4, char *a5);
/**
-154
View File
@@ -1,154 +0,0 @@
/**
* @file dict.c
*
* @brief Implementation of dict_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#include "dict.h"
#include <utils/linked_list.h>
typedef struct private_dict_t private_dict_t;
/**
* private data of dict
*/
struct private_dict_t {
/**
* public functions
*/
dict_t public;
/**
* baaah, we really should have a hashtable for this
*/
linked_list_t *list;
/**
* key comparator function
*/
bool(*key_comparator)(void*,void*);
/**
* destructor function for key
*/
void(*key_destructor)(void*);
/**
* destructor function for value
*/
void(*value_destructor)(void*);
};
/**
* key value pair to store entries
*/
typedef struct {
void *key;
void *value;
} key_value_t;
/**
* Implementation of dict_t.get.
*/
static void* get(private_dict_t *this, void *key)
{
key_value_t *kv;
iterator_t *iterator;
void *value = NULL;
iterator = this->list->create_iterator(this->list, TRUE);
while (iterator->iterate(iterator, (void**)&kv))
{
if (this->key_comparator(kv->key, key))
{
value = kv->value;
break;
}
}
iterator->destroy(iterator);
return value;
}
/**
* Implementation of dict_t.set.
*/
static void set(private_dict_t *this, void *key, void *value)
{
/* we don't overwrite, just prepend */
key_value_t *kv = malloc_thing(key_value_t);
kv->key = key;
kv->value = value;
this->list->insert_first(this->list, kv);
}
/**
* comparator for strings
*/
bool dict_streq(void *a, void *b)
{
return streq(a, b);
}
/**
* Implementation of dict_t.destroy
*/
static void destroy(private_dict_t *this)
{
key_value_t *kv;
while (this->list->remove_last(this->list, (void**)&kv) == SUCCESS)
{
if (this->key_destructor)
{
this->key_destructor(kv->key);
}
if (this->value_destructor)
{
this->value_destructor(kv->value);
}
free(kv);
}
this->list->destroy(this->list);
free(this);
}
/*
* see header file
*/
dict_t *dict_create(bool(*key_comparator)(void*,void*),
void(*key_destructor)(void*),
void(*value_destructor)(void*))
{
private_dict_t *this = malloc_thing(private_dict_t);
this->public.set = (void(*)(dict_t*, void *key, void *value))set;
this->public.get = (void*(*)(dict_t*, void *key))get;
this->public.destroy = (void(*)(dict_t*))destroy;
this->list = linked_list_create();
this->key_comparator = key_comparator;
this->key_destructor = key_destructor;
this->value_destructor = value_destructor;
return &this->public;
}
-73
View File
@@ -1,73 +0,0 @@
/**
* @file dict.h
*
* @brief Interface of dict_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#ifndef DICT_H_
#define DICT_H_
#include <library.h>
typedef struct dict_t dict_t;
/**
* @brief Dictionary type, key value stuff.
*/
struct dict_t {
/**
* @brief Set a value in the dict.
*
* @param key key to set
* @param value value, NULL to unset key
* @return
*/
void (*set)(dict_t *this, void *key, void *value);
/**
* @brief Get a value form the dict.
*
* @param key key to get value of
* @return assigned value, NULL if not found
*/
void* (*get)(dict_t *this, void *key);
/**
* @brief Destroy a dict instance.
*/
void (*destroy)(dict_t *this);
};
/**
* @brief Key comparator function for strings
*/
bool dict_streq(void *a, void *b);
/**
* @brief Create a dict instance.
*
* @param free_key TRUE to free() keys on destruction
* @param
*/
dict_t *dict_create(bool(*key_comparator)(void*,void*),
void(*key_destructor)(void*),
void(*value_destructor)(void*));
#endif /* DICT_H_ */
+14 -12
View File
@@ -28,6 +28,7 @@
#include <fcgiapp.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <utils/linked_list.h>
@@ -183,7 +184,6 @@ static void dispatch(private_dispatcher_t *this)
while (TRUE)
{
request_t *request;
response_t *response;
session_entry_t *current, *found = NULL;
iterator_t *iterator;
time_t now;
@@ -200,8 +200,11 @@ static void dispatch(private_dispatcher_t *this)
}
/* prepare */
response = response_create(&fcgi_req);
request = request_create(&fcgi_req);
request = request_create(&fcgi_req, TRUE);
if (request == NULL)
{
continue;
}
sid = request->get_cookie(request, "SID");
now = time(NULL);
@@ -244,7 +247,7 @@ static void dispatch(private_dispatcher_t *this)
}
/* start processing */
found->session->process(found->session, request, response);
found->session->process(found->session, request);
found->used = time(NULL);
/* release session */
@@ -255,7 +258,6 @@ static void dispatch(private_dispatcher_t *this)
/* cleanup */
request->destroy(request);
response->destroy(response);
/*
FCGX_FPrintF(fcgi_req.out, "<ul>");
@@ -323,8 +325,8 @@ static void destroy(private_dispatcher_t *this)
/*
* see header file
*/
dispatcher_t *dispatcher_create(int timeout, context_constructor_t constructor,
void *param)
dispatcher_t *dispatcher_create(char *socket, int timeout,
context_constructor_t constructor, void *param)
{
private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
@@ -343,11 +345,11 @@ dispatcher_t *dispatcher_create(int timeout, context_constructor_t constructor,
FCGX_Init();
#ifdef FCGI_SOCKET
unlink(FCGI_SOCKET);
this->fd = FCGX_OpenSocket(FCGI_SOCKET, 10);
#endif /* FCGI_SOCKET */
if (socket)
{
unlink(socket);
this->fd = FCGX_OpenSocket(socket, 10);
}
return &this->public;
}
+2 -1
View File
@@ -73,11 +73,12 @@ struct dispatcher_t {
* The context constructor is invoked to create a session context for
* each session.
*
* @param socket FastCGI socket path, NULL for dynamic
* @param timeout session timeout
* @param constructor construction function for session context
* @param param parameter to supply to context constructor
*/
dispatcher_t *dispatcher_create(int timeout,
dispatcher_t *dispatcher_create(char *socket, int timeout,
context_constructor_t constructor, void *param);
#endif /* DISPATCHER_H_ */
+185 -138
View File
@@ -24,9 +24,10 @@
#include "request.h"
#include <library.h>
#include <stdlib.h>
#include <dict.h>
#include <string.h>
#include <ClearSilver/ClearSilver.h>
typedef struct private_request_t private_request_t;
@@ -41,27 +42,111 @@ struct private_request_t {
request_t public;
/**
* the associated fcgi request
* FastCGI request object
*/
FCGX_Request *req;
/**
* list of cookies
* ClearSilver CGI Kit context
*/
dict_t *cookies;
CGI *cgi;
/**
* list of post data
* ClearSilver HDF dataset for this request
*/
dict_t *posts;
HDF *hdf;
};
/**
* thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
* ClearSilver cgiwrap is not threadsave, so we use a private
* context for each thread.
*/
__thread FCGX_Request *req;
/**
* length of param list in req->envp
*/
__thread int req_env_len;
/**
* fcgiwrap read callback
*/
static int read_cb(void *null, char *buf, int size)
{
return FCGX_GetStr(buf, size, req->in);
}
/**
* fcgiwrap writef callback
*/
static int writef_cb(void *null, const char *format, va_list args)
{
FCGX_VFPrintF(req->out, format, args);
return 0;
}
/**
* fcgiwrap write callback
*/
static int write_cb(void *null, const char *buf, int size)
{
return FCGX_PutStr(buf, size, req->out);
}
/**
* fcgiwrap getenv callback
*/
static char *getenv_cb(void *null, const char *key)
{
char *value;
value = FCGX_GetParam(key, req->envp);
return value ? strdup(value) : NULL;
}
/**
* fcgiwrap getenv callback
*/
static int putenv_cb(void *null, const char *key, const char *value)
{
/* not supported */
return 1;
}
/**
* fcgiwrap iterenv callback
*/
static int iterenv_cb(void *null, int num, char **key, char **value)
{
*key = NULL;
*value = NULL;
if (num > req_env_len)
{
char *eq;
eq = strchr(req->envp[num], '=');
if (eq)
{
*key = strndup(req->envp[num], eq - req->envp[num]);
*value = strdup(eq + 1);
}
if (*key == NULL || *value == NULL)
{
free(*key);
free(*value);
return 1;
}
}
return 0;
}
/**
* Implementation of request_t.get_cookie.
*/
static char* get_cookie(private_request_t *this, char *name)
{
return this->cookies->get(this->cookies, name);
return hdf_get_valuef(this->hdf, "Cookie.%s", name);
}
/**
@@ -76,152 +161,74 @@ static char* get_path(private_request_t *this)
/**
* Implementation of request_t.get_post_data.
*/
static char* get_post_data(private_request_t *this, char *name)
static char* get_query_data(private_request_t *this, char *name)
{
return this->posts->get(this->posts, name);
return hdf_get_valuef(this->hdf, "Query.%s", name);
}
/**
* convert 2 digit hex string to a integer
* Implementation of request_t.add_cookie.
*/
static char hex2char(char *hex)
static void add_cookie(private_request_t *this, char *name, char *value)
{
static char hexdig[] = "00112233445566778899AaBbCcDdEeFf";
cgi_cookie_set (this->cgi, name, value,
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
NULL, NULL, 0, 0);
}
return (strchr(hexdig, hex[1]) - hexdig)/2 +
((strchr(hexdig, hex[0]) - hexdig)/2 * 16);
/**
* Implementation of request_t.redirect.
*/
static void redirect(private_request_t *this, char *location)
{
FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n",
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
*location == '/' ? "" : "/", location);
}
/**
* unescape a string up to the delimiter, and return a clone
* Implementation of request_t.get_base.
*/
static char *unescape(char **pos, char delimiter)
static char* get_base(private_request_t *this)
{
char *ptr, *res, *end, code[3] = {'\0','\0','\0'};
if (**pos == '\0')
{
return NULL;
}
ptr = strchr(*pos, delimiter);
if (ptr)
{
res = strndup(*pos, ptr - *pos);
*pos = ptr + 1;
}
else
{
res = strdup(*pos);
*pos = "";
}
end = res + strlen(res) + 1;
/* replace '+' with ' ' */
ptr = res;
while ((ptr = strchr(ptr, '+')))
{
*ptr = ' ';
}
/* replace %HH with its ascii value */
ptr = res;
while ((ptr = strchr(ptr, '%')))
{
if (ptr > end - 2)
{
break;
}
strncpy(code, ptr + 1, 2);
*ptr = hex2char(code);
memmove(ptr + 1, ptr + 3, end - (ptr + 3));
}
return res;
return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
}
/**
* parse the http POST data
* Implementation of request_t.render.
*/
static void parse_post(private_request_t *this)
static void render(private_request_t *this, char *template)
{
char buf[4096], *pos, *name, *value;
int len;
if (!streq(FCGX_GetParam("REQUEST_METHOD", this->req->envp), "POST") ||
!streq(FCGX_GetParam("CONTENT_TYPE", this->req->envp),
"application/x-www-form-urlencoded"))
{
return;
}
NEOERR* err;
len = FCGX_GetStr(buf, sizeof(buf) - 1, this->req->in);
if (len != atoi(FCGX_GetParam("CONTENT_LENGTH", this->req->envp)))
err = cgi_display(this->cgi, template);
if (err)
{
return;
}
buf[len] = 0;
pos = buf;
while (TRUE)
{
name = unescape(&pos, '=');
if (name)
{
value = unescape(&pos, '&');
if (value)
{
this->posts->set(this->posts, name, value);
continue;
}
else
{
free(name);
}
}
break;
cgi_neo_error(this->cgi, err);
nerr_log_error(err);
}
return;
}
/**
* parse the requests cookies
* Implementation of request_t.set.
*/
static void parse_cookies(private_request_t *this)
static void set(private_request_t *this, char *key, char *value)
{
char *str, *pos;
char *name, *value;
str = FCGX_GetParam("HTTP_COOKIE", this->req->envp);
while (str)
{
if (*str == ' ')
{
str++;
continue;
}
pos = strchr(str, '=');
if (pos == NULL)
{
break;
}
name = strndup(str, pos - str);
value = NULL;
str = pos + 1;
if (str)
{
pos = strchr(str, ';');
if (pos)
{
value = strndup(str, pos - str);
}
else
{
value = strdup(str);
}
}
this->cookies->set(this->cookies, name, value);
if (pos == NULL)
{
break;
}
str = pos + 1;
}
hdf_set_value(this->hdf, key, value);
}
/**
* Implementation of request_t.setf.
*/
static void setf(private_request_t *this, char *format, ...)
{
va_list args;
va_start(args, format);
hdf_set_valuevf(this->hdf, format, args);
va_end(args);
}
/**
@@ -229,30 +236,70 @@ static void parse_cookies(private_request_t *this)
*/
static void destroy(private_request_t *this)
{
this->cookies->destroy(this->cookies);
this->posts->destroy(this->posts);
cgi_destroy(&this->cgi);
free(this);
}
/*
* see header file
*/
request_t *request_create(FCGX_Request *request)
request_t *request_create(FCGX_Request *request, bool debug)
{
NEOERR* err;
static bool initialized = FALSE;
private_request_t *this = malloc_thing(private_request_t);
this->public.get_path = (char*(*)(request_t*))get_path;
this->public.get_base = (char*(*)(request_t*))get_base;
this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
this->public.get_post_data = (char*(*)(request_t*, char *name))get_post_data;
this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
this->public.redirect = (void(*)(request_t*, char *location))redirect;
this->public.render = (void(*)(request_t*,char*))render;
this->public.set = (void(*)(request_t*, char *, char*))set;
this->public.setf = (void(*)(request_t*, char *format, ...))setf;
this->public.destroy = (void(*)(request_t*))destroy;
if (!initialized)
{
cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
getenv_cb, putenv_cb, iterenv_cb);
initialized = TRUE;
}
this->req = request;
this->cookies = dict_create(dict_streq, free, free);
this->posts = dict_create(dict_streq, free, free);
req = request;
req_env_len = 0;
while (req->envp[req_env_len] != NULL)
{
req_env_len++;
}
parse_cookies(this);
parse_post(this);
err = hdf_init(&this->hdf);
if (!err)
{
hdf_set_value(this->hdf, "base", get_base(this));
hdf_set_value(this->hdf, "Config.NoCache", "true");
if (!debug)
{
hdf_set_value(this->hdf, "Config.TimeFooter", "0");
hdf_set_value(this->hdf, "Config.CompressionEnabled", "1");
hdf_set_value(this->hdf, "Config.WhiteSpaceStrip", "2");
}
return &this->public;
err = cgi_init(&this->cgi, this->hdf);
if (!err)
{
err = cgi_parse(this->cgi);
if (!err)
{
return &this->public;
}
cgi_destroy(&this->cgi);
}
}
nerr_log_error(err);
free(this);
return NULL;
}
+59 -5
View File
@@ -23,8 +23,8 @@
#ifndef REQUEST_H_
#define REQUEST_H_
#include <fcgiapp.h>
#include <library.h>
typedef struct request_t request_t;
@@ -34,6 +34,14 @@ typedef struct request_t request_t;
*/
struct request_t {
/**
* @brief Add a cookie to the reply (Set-Cookie header).
*
* @param name name of the cookie to set
* @param value value of the cookie
*/
void (*add_cookie)(request_t *this, char *name, char *value);
/**
* @brief Get a cookie the client sent in the request.
*
@@ -50,12 +58,57 @@ struct request_t {
char* (*get_path)(request_t *this);
/**
* @brief Get a post variable included in the request.
* @brief Get the base path of the application.
*
* @param name name of the POST variable
* @return base path
*/
char* (*get_base)(request_t *this);
/**
* @brief Get a post/get variable included in the request.
*
* @param name name of the POST/GET variable
* @return value, NULL if not found
*/
char* (*get_post_data)(request_t *this, char *name);
char* (*get_query_data)(request_t *this, char *name);
/**
* @brief Redirect the client to another location.
*
* @param location location to redirect to
*/
void (*redirect)(request_t *this, char *location);
/**
* @brief Set a template value.
*
* @param key key to set
* @param value value to set key to
*/
void (*set)(request_t *this, char *key, char *value);
/**
* @brief Set a template value using format strings.
*
* Format string is in the form "key=value", where printf like format
* substitution occurs over the whole string.
*
* @param format printf like format string
* @param ... variable argument list
*/
void (*setf)(request_t *this, char *format, ...);
/**
* @brief Render a template.
*
* The render() function additionally sets a HDF variable "base"
* which points to the root of the web application and allows to point to
* other targets without to worry about path location.
*
* @param template clearsilver template file location
* @return rendered template string
*/
void (*render)(request_t *this, char *template);
/**
* @brief Destroy the request_t.
@@ -67,7 +120,8 @@ struct request_t {
* @brief Create a request from the fastcgi struct.
*
* @param request the FCGI request
* @param debug no stripping, no compression, timing information
*/
request_t *request_create(FCGX_Request *request);
request_t *request_create(FCGX_Request *request, bool debug);
#endif /* REQUEST_H_ */
-233
View File
@@ -1,233 +0,0 @@
/**
* @file response.c
*
* @brief Implementation of response_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#include "response.h"
#include <stdlib.h>
#include <stdarg.h>
#include <utils/linked_list.h>
typedef struct {
char *name;
char *value;
} name_value_t;
/**
* create name value pair
*/
static name_value_t *name_value_create(char *name, char *value)
{
name_value_t *this = malloc_thing(name_value_t);
this->name = strdup(name);
this->value = strdup(value);
return this;
}
/**
* destroy a name value pair
*/
static void name_value_destroy(name_value_t *this)
{
free(this->name);
free(this->value);
free(this);
}
typedef struct private_response_t private_response_t;
/**
* private data of the task manager
*/
struct private_response_t {
/**
* public functions
*/
response_t public;
/**
* the associated fcgi request
*/
FCGX_Request *req;
/**
* Content type
*/
char *content_type;
/**
* list of cookies (name_value_t)
*/
linked_list_t *cookies;
/**
* list of custom headers (name_value_t)
*/
linked_list_t *headers;
/**
* headers already written?
*/
bool started;
};
/**
* write the headers, if not already written
*/
static void write_headers(private_response_t *this)
{
iterator_t *iterator;
name_value_t *current;
FCGX_FPrintF(this->req->out, "Content-type: %s\n", this->content_type);
iterator = this->cookies->create_iterator(this->cookies, TRUE);
while (iterator->iterate(iterator, (void**)&current))
{
FCGX_FPrintF(this->req->out, "Set-Cookie: %s=%s; path=%s\n",
current->name, current->value,
FCGX_GetParam("SCRIPT_NAME", this->req->envp));
}
iterator->destroy(iterator);
iterator = this->cookies->create_iterator(this->headers, TRUE);
while (iterator->iterate(iterator, (void**)&current))
{
FCGX_FPrintF(this->req->out, "%s: %s\n",
current->name, current->value);
}
iterator->destroy(iterator);
FCGX_PutChar('\n', this->req->out);
this->started = TRUE;
}
/**
* Implementation of response_t.print.
*/
static void print_(private_response_t *this, char *str)
{
if (!this->started)
{
write_headers(this);
}
FCGX_PutS(str, this->req->out);
}
/**
* Implementation of response_t.printf.
*/
static void printf_(private_response_t *this, char *format, ...)
{
va_list args;
if (!this->started)
{
write_headers(this);
}
va_start(args, format);
FCGX_VFPrintF(this->req->out, format, args);
va_end(args);
}
/**
* Implementation of response_t.add_header.
*/
static void add_header(private_response_t *this, char *name, char *value)
{
this->headers->insert_last(this->headers, name_value_create(name, value));
}
/**
* Implementation of response_t.set_content_type.
*/
static void set_content_type(private_response_t *this, char *type)
{
free(this->content_type);
this->content_type = strdup(type);
}
/**
* Implementation of response_t.add_cookie.
*/
static void add_cookie(private_response_t *this, char *name, char *value)
{
this->cookies->insert_last(this->cookies, name_value_create(name, value));
}
/**
* Implementation of response_t.redirect.
*/
static void redirect(private_response_t *this, char *location)
{
FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n",
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
*location == '/' ? "" : "/", location);
}
/**
* Implementation of response_t.get_base.
*/
static char* get_base(private_response_t *this)
{
return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
}
/**
* Implementation of response_t.destroy
*/
static void destroy(private_response_t *this)
{
this->headers->destroy_function(this->headers, (void*)name_value_destroy);
this->cookies->destroy_function(this->cookies, (void*)name_value_destroy);
free(this->content_type);
free(this);
}
/*
* see header file
*/
response_t *response_create(FCGX_Request *request)
{
private_response_t *this = malloc_thing(private_response_t);
this->public.print = (void(*)(response_t*, char *str))print_;
this->public.printf = (void(*)(response_t*, char *format, ...))printf_;
this->public.add_header = (void(*)(response_t*, char *name, char *value))add_header;
this->public.set_content_type = (void(*)(response_t*, char *type))set_content_type;
this->public.add_cookie = (void(*)(response_t*, char *name, char *value))add_cookie;
this->public.redirect = (void(*)(response_t*, char *location))redirect;
this->public.get_base = (char*(*)(response_t*))get_base;
this->public.destroy = (void(*)(response_t*))destroy;
this->req = request;
this->headers = linked_list_create();
this->cookies = linked_list_create();
this->content_type = strdup("text/html");
this->started = FALSE;
return &this->public;
}
-102
View File
@@ -1,102 +0,0 @@
/**
* @file response.h
*
* @brief Interface of response_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#ifndef RESPONSE_H_
#define RESPONSE_H_
#include <fcgiapp.h>
typedef struct response_t response_t;
/**
* @brief A HTTP response, wraps response functionality around FCGX_Request.
*
*/
struct response_t {
/**
* @brief Write a string to the client.
*
* @param str string to write
*/
void (*print)(response_t *this, char *str);
/**
* @brief Write a printf like format string to client.
*
* @param format printf like format string
* @param ... variable argument list
*/
void (*printf)(response_t *this, char *format, ...);
/**
* @brief Add a custom header to the response.
*
* @param name name of the header
* @param value value of the header
*/
void (*add_header)(response_t *this, char *name, char *value);
/**
* @brief Set the content type (Content-Type header).
*
* @param type content type (e.g. text/html)
*/
void (*set_content_type)(response_t *this, char *type);
/**
* @brief Add a cookie to the response (Set-Cookie header).
*
* @param name name of the cookie to set
* @param value value of the cookie
*/
void (*add_cookie)(response_t *this, char *name, char *value);
/**
* @brief Redirect the client to another location.
*
* @param location location to redirect to
*/
void (*redirect)(response_t *this, char *location);
/**
* @brief Get the base path of the application.
*
* @return base path
*/
char* (*get_base)(response_t *this);
/**
* @brief Destroy a response_t.
*/
void (*destroy) (response_t *this);
};
/**
* @brief Create a response.
*
* @param request the FCGI request structure
*/
response_t *response_create(FCGX_Request *request);
#endif /* RESPONSE_H_ */
+7 -12
View File
@@ -70,7 +70,7 @@ static void add_controller(private_session_t *this, controller_t *controller)
/**
* Create a session ID and a cookie
*/
static void create_sid(private_session_t *this, response_t *response)
static void create_sid(private_session_t *this, request_t *request)
{
char buf[16];
chunk_t chunk = chunk_from_buf(buf);
@@ -78,15 +78,14 @@ static void create_sid(private_session_t *this, response_t *response)
randomizer->get_pseudo_random_bytes(randomizer, sizeof(buf), buf);
asprintf(&this->sid, "%#B", &chunk);
response->add_cookie(response, "SID", this->sid);
request->add_cookie(request, "SID", this->sid);
randomizer->destroy(randomizer);
}
/**
* Implementation of session_t.process.
*/
static void process(private_session_t *this,
request_t *request, response_t *response)
static void process(private_session_t *this, request_t *request)
{
char *pos, *path, *controller, *action;
iterator_t *iterator;
@@ -95,7 +94,7 @@ static void process(private_session_t *this,
if (this->sid == NULL)
{
create_sid(this, response);
create_sid(this, request);
}
path = request->get_path(request);
@@ -125,7 +124,7 @@ static void process(private_session_t *this,
{
if (streq(current->get_name(current), controller))
{
current->handle(current, request, response, action, NULL, NULL, NULL, NULL);
current->handle(current, request, action, NULL, NULL, NULL, NULL);
handled = TRUE;
break;
}
@@ -138,11 +137,7 @@ static void process(private_session_t *this,
if (this->controllers->get_first(this->controllers,
(void**)&current) == SUCCESS)
{
response->redirect(response, current->get_name(current));
}
else
{
response->printf(response, "No controllers loaded!\n");
request->redirect(request, current->get_name(current));
}
}
}
@@ -174,7 +169,7 @@ session_t *session_create(context_t *context)
private_session_t *this = malloc_thing(private_session_t);
this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
this->public.process = (void(*)(session_t*, request_t*,response_t*))process;
this->public.process = (void(*)(session_t*,request_t*))process;
this->public.get_sid = (char*(*)(session_t*))get_sid;
this->public.destroy = (void(*)(session_t*))destroy;
+1 -3
View File
@@ -24,7 +24,6 @@
#define SESSION_H_
#include "request.h"
#include "response.h"
#include "controller.h"
typedef struct session_t session_t;
@@ -53,9 +52,8 @@ struct session_t {
* @brief Process a request in this session.
*
* @param request request to process
* @param response response to send
*/
void (*process)(session_t *this, request_t *request, response_t *response);
void (*process)(session_t *this, request_t *request);
/**
* @brief Destroy the session_t.
-138
View File
@@ -1,138 +0,0 @@
/**
* @file template.c
*
* @brief Implementation of template_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#include "template.h"
#include <ClearSilver/ClearSilver.h>
#include <library.h>
typedef struct private_template_t private_template_t;
/**
* private data of the task manager
*/
struct private_template_t {
/**
* public functions
*/
template_t public;
/**
* template file
*/
char *file;
/**
* clearsilver HDF dataset
*/
HDF *hdf;
};
/**
* clearsilver cs_render callback function
*/
static NEOERR* render_cb(response_t *response, char *str)
{
response->print(response, str);
return NULL;
}
/**
* Implementation of template_t.render.
*/
static void render(private_template_t *this, response_t *response)
{
NEOERR* err;
CSPARSE *parse;
hdf_set_value(this->hdf, "base", response->get_base(response));
err = cs_init(&parse, this->hdf);
if (!err)
{
err = cs_parse_file(parse, this->file);
if (!err)
{
err = cs_render(parse, response, (CSOUTFUNC)render_cb);
if (!err)
{
cs_destroy(&parse);
return;
}
}
cs_destroy(&parse);
}
nerr_log_error(err);
return;
}
/**
* Implementation of template_t.set.
*/
static void set(private_template_t *this, char *key, char *value)
{
hdf_set_value(this->hdf, key, value);
}
/**
* Implementation of template_t.setf.
*/
static void setf(private_template_t *this, char *format, ...)
{
va_list args;
va_start(args, format);
hdf_set_valuevf(this->hdf, format, args);
va_end(args);
}
/**
* Implementation of template_t.destroy
*/
static void destroy(private_template_t *this)
{
hdf_destroy(&this->hdf);
free(this->file);
free(this);
}
/*
* see header file
*/
template_t *template_create(char *file)
{
private_template_t *this = malloc_thing(private_template_t);
this->public.render = (void(*)(template_t*,response_t*))render;
this->public.set = (void(*)(template_t*, char *, char*))set;
this->public.setf = (void(*)(template_t*, char *format, ...))setf;
this->public.destroy = (void(*)(template_t*))destroy;
this->file = strdup(file);
this->hdf = NULL;
hdf_init(&this->hdf);
return &this->public;
}
-80
View File
@@ -1,80 +0,0 @@
/**
* @file template.h
*
* @brief Interface of template_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#ifndef TEMPLATE_H_
#define TEMPLATE_H_
#include "response.h"
typedef struct template_t template_t;
/**
* @brief Template engine based on ClearSilver.
*
*/
struct template_t {
/**
* @brief Set a template value.
*
* @param key key to set
* @param value value to set key to
*/
void (*set)(template_t *this, char *key, char *value);
/**
* @brief Set a template value using format strings.
*
* Format string is in the form "key=value", where printf like format
* substitution occurs over the whole string.
*
* @param format printf like format string
* @param ... variable argument list
*/
void (*setf)(template_t *this, char *format, ...);
/**
* @brief Render a template to a response object.
*
* The render() function additionally sets a clearsilver variable "base"
* which points to the root of the web application and allows to point to
* other targets without to worry about path location.
*
* @param response response to render to
* @return rendered template string
*/
void (*render)(template_t *this, response_t *response);
/**
* @brief Destroy the template_t.
*/
void (*destroy) (template_t *this);
};
/**
* @brief Create a template from a file.
*
* @param file template file
*/
template_t *template_create(char *file);
#endif /* TEMPLATE_H_ */