libfast: add a fast_ prefix to all classes, avoiding namespace clashes
authorMartin Willi <martin@revosec.ch>
Wed, 17 Jul 2013 09:50:45 +0000 (11:50 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 10:24:38 +0000 (12:24 +0200)
45 files changed:
src/libfast/Makefile.am
src/libfast/context.h [deleted file]
src/libfast/controller.h [deleted file]
src/libfast/dispatcher.c [deleted file]
src/libfast/dispatcher.h [deleted file]
src/libfast/fast_context.h [new file with mode: 0644]
src/libfast/fast_controller.h [new file with mode: 0644]
src/libfast/fast_dispatcher.c [new file with mode: 0644]
src/libfast/fast_dispatcher.h [new file with mode: 0644]
src/libfast/fast_filter.h [new file with mode: 0644]
src/libfast/fast_request.c [new file with mode: 0644]
src/libfast/fast_request.h [new file with mode: 0644]
src/libfast/fast_session.c [new file with mode: 0644]
src/libfast/fast_session.h [new file with mode: 0644]
src/libfast/fast_smtp.c [new file with mode: 0644]
src/libfast/fast_smtp.h [new file with mode: 0644]
src/libfast/filter.h [deleted file]
src/libfast/request.c [deleted file]
src/libfast/request.h [deleted file]
src/libfast/session.c [deleted file]
src/libfast/session.h [deleted file]
src/libfast/smtp.c [deleted file]
src/libfast/smtp.h [deleted file]
src/manager/controller/auth_controller.c
src/manager/controller/auth_controller.h
src/manager/controller/config_controller.c
src/manager/controller/config_controller.h
src/manager/controller/control_controller.c
src/manager/controller/control_controller.h
src/manager/controller/gateway_controller.c
src/manager/controller/gateway_controller.h
src/manager/controller/ikesa_controller.c
src/manager/controller/ikesa_controller.h
src/manager/main.c
src/manager/manager.c
src/manager/manager.h
src/medsrv/controller/peer_controller.c
src/medsrv/controller/peer_controller.h
src/medsrv/controller/user_controller.c
src/medsrv/controller/user_controller.h
src/medsrv/filter/auth_filter.c
src/medsrv/filter/auth_filter.h
src/medsrv/main.c
src/medsrv/user.c
src/medsrv/user.h

index df5b650..db91048 100644 (file)
@@ -1,12 +1,13 @@
 ipseclib_LTLIBRARIES = libfast.la
 
 libfast_la_SOURCES = \
-       dispatcher.c request.c session.c smtp.c
+       fast_dispatcher.c fast_request.c fast_session.c fast_smtp.c
 
 if USE_DEV_HEADERS
 fast_includedir = ${dev_headers}/fast
 nobase_fast_include_HEADERS = \
-       context.h controller.h dispatcher.h filter.h request.h session.h smtp.h
+       fast_context.h fast_controller.h fast_dispatcher.h fast_filter.h \
+       fast_request.h fast_session.h fast_smtp.h
 endif
 
 libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
diff --git a/src/libfast/context.h b/src/libfast/context.h
deleted file mode 100644 (file)
index 4f8d11d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup context context
- * @{ @ingroup libfast
- */
-
-#ifndef CONTEXT_H_
-#define CONTEXT_H_
-
-typedef struct context_t context_t;
-
-/**
- * Constructor function for a user specific context.
- */
-typedef context_t *(*context_constructor_t)(void *param);
-
-/**
- * User specific session context, to extend.
- */
-struct context_t {
-
-       /**
-        * Destroy the context_t.
-        */
-       void (*destroy) (context_t *this);
-};
-
-#endif /** CONTEXT_H_ @}*/
diff --git a/src/libfast/controller.h b/src/libfast/controller.h
deleted file mode 100644 (file)
index 7a7efc7..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup controller controller
- * @{ @ingroup libfast
- */
-
-#ifndef CONTROLLER_H_
-#define CONTROLLER_H_
-
-#include "request.h"
-#include "context.h"
-
-typedef struct controller_t controller_t;
-
-/**
- * Constructor function for a controller.
- *
- * @param context              session specific context, implements context_t
- * @param param                        user supplied param, as registered to the dispatcher
- */
-typedef controller_t *(*controller_constructor_t)(context_t* context, void *param);
-
-/**
- * Controller interface, to be implemented by users controllers.
- *
- * Controller instances get created per session, so each session has an
- * associated set of private controller instances.
- * The controller handle function is called for each incoming request.
- */
-struct controller_t {
-
-       /**
-        * Get the name of the controller.
-        *
-        * @return                              name of the controller
-        */
-       char* (*get_name)(controller_t *this);
-
-       /**
-        * Handle a HTTP request for that controller.
-        *
-        * Request URLs are parsed in the form
-        * controller_name/p1/p2/p3/p4/p5 with a maximum of 5 parameters. Each
-        * parameter not found in the request URL is set to NULL.
-        *
-        * @param request               HTTP request
-        * @param p1                    first parameter
-        * @param p2                    second parameter
-        * @param p3                    third parameter
-        * @param p4                    forth parameter
-        * @param p5                    fifth parameter
-        * @return
-        */
-       void (*handle)(controller_t *this, request_t *request,
-                                  char *p1, char *p2, char *p3, char *p4, char *p5);
-
-       /**
-        * Destroy the controller instance.
-        */
-       void (*destroy) (controller_t *this);
-};
-
-#endif /** CONTROLLER_H_ @}*/
diff --git a/src/libfast/dispatcher.c b/src/libfast/dispatcher.c
deleted file mode 100644 (file)
index e5a02c6..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * 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 "dispatcher.h"
-
-#include "request.h"
-#include "session.h"
-
-#include <fcgiapp.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <utils/debug.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-#include <collections/linked_list.h>
-#include <collections/hashtable.h>
-
-/** Intervall to check for expired sessions, in seconds */
-#define CLEANUP_INTERVAL 30
-
-typedef struct private_dispatcher_t private_dispatcher_t;
-
-/**
- * private data of the task manager
- */
-struct private_dispatcher_t {
-
-       /**
-        * public functions
-        */
-       dispatcher_t public;
-
-       /**
-        * fcgi socket fd
-        */
-       int fd;
-
-       /**
-        * thread list
-        */
-       thread_t **threads;
-
-       /**
-        * number of threads in "threads"
-        */
-       int thread_count;
-
-       /**
-        * session locking mutex
-        */
-       mutex_t *mutex;
-
-       /**
-        * Hahstable with active sessions
-        */
-       hashtable_t *sessions;
-
-       /**
-        * session timeout
-        */
-       time_t timeout;
-
-       /**
-        * timestamp of last session cleanup round
-        */
-       time_t last_cleanup;
-
-       /**
-        * running in debug mode?
-        */
-       bool debug;
-
-       /**
-        * List of controllers controller_constructor_t
-        */
-       linked_list_t *controllers;
-
-       /**
-        * List of filters filter_constructor_t
-        */
-       linked_list_t *filters;
-
-       /**
-        * constructor function to create session context (in controller_entry_t)
-        */
-       context_constructor_t context_constructor;
-
-       /**
-        * user param to context constructor
-        */
-       void *param;
-};
-
-typedef struct {
-       /** constructor function */
-       controller_constructor_t constructor;
-       /** parameter to constructor */
-       void *param;
-} controller_entry_t;
-
-typedef struct {
-       /** constructor function */
-       filter_constructor_t constructor;
-       /** parameter to constructor */
-       void *param;
-} filter_entry_t;
-
-typedef struct {
-       /** session instance */
-       session_t *session;
-       /** condvar to wait for session */
-       condvar_t *cond;
-       /** client host address, to prevent session hijacking */
-       char *host;
-       /** TRUE if session is in use */
-       bool in_use;
-       /** last use of the session */
-       time_t used;
-       /** has the session been closed by the handler? */
-       bool closed;
-} session_entry_t;
-
-/**
- * create a session and instanciate controllers
- */
-static session_t* load_session(private_dispatcher_t *this)
-{
-       enumerator_t *enumerator;
-       controller_entry_t *centry;
-       filter_entry_t *fentry;
-       session_t *session;
-       context_t *context = NULL;
-       controller_t *controller;
-       filter_t *filter;
-
-       if (this->context_constructor)
-       {
-               context = this->context_constructor(this->param);
-       }
-       session = session_create(context);
-
-       enumerator = this->controllers->create_enumerator(this->controllers);
-       while (enumerator->enumerate(enumerator, &centry))
-       {
-               controller = centry->constructor(context, centry->param);
-               session->add_controller(session, controller);
-       }
-       enumerator->destroy(enumerator);
-
-       enumerator = this->filters->create_enumerator(this->filters);
-       while (enumerator->enumerate(enumerator, &fentry))
-       {
-               filter = fentry->constructor(context, fentry->param);
-               session->add_filter(session, filter);
-       }
-       enumerator->destroy(enumerator);
-
-       return session;
-}
-
-/**
- * create a new session entry
- */
-static session_entry_t *session_entry_create(private_dispatcher_t *this,
-                                                                                        char *host)
-{
-       session_entry_t *entry;
-       session_t *session;
-
-       session = load_session(this);
-       if (!session)
-       {
-               return NULL;
-       }
-       INIT(entry,
-               .cond = condvar_create(CONDVAR_TYPE_DEFAULT),
-               .session = session,
-               .host = strdup(host),
-               .used = time_monotonic(NULL),
-       );
-       return entry;
-}
-
-/**
- * destroy a session
- */
-static void session_entry_destroy(session_entry_t *entry)
-{
-       entry->session->destroy(entry->session);
-       entry->cond->destroy(entry->cond);
-       free(entry->host);
-       free(entry);
-}
-
-METHOD(dispatcher_t, add_controller, void,
-       private_dispatcher_t *this, controller_constructor_t constructor,
-       void *param)
-{
-       controller_entry_t *entry;
-
-       INIT(entry,
-               .constructor = constructor,
-               .param = param,
-       );
-       this->controllers->insert_last(this->controllers, entry);
-}
-
-METHOD(dispatcher_t, add_filter, void,
-       private_dispatcher_t *this, filter_constructor_t constructor, void *param)
-{
-       filter_entry_t *entry;
-
-       INIT(entry,
-               .constructor = constructor,
-               .param = param,
-       );
-       this->filters->insert_last(this->filters, entry);
-}
-
-/**
- * Hashtable hash function
- */
-static u_int session_hash(char *sid)
-{
-       return chunk_hash(chunk_create(sid, strlen(sid)));
-}
-
-/**
- * Hashtable equals function
- */
-static bool session_equals(char *sid1, char *sid2)
-{
-       return streq(sid1, sid2);
-}
-
-/**
- * Cleanup unused sessions
- */
-static void cleanup_sessions(private_dispatcher_t *this, time_t now)
-{
-       if (this->last_cleanup < now - CLEANUP_INTERVAL)
-       {
-               char *sid;
-               session_entry_t *entry;
-               enumerator_t *enumerator;
-               linked_list_t *remove;
-
-               this->last_cleanup = now;
-               remove = linked_list_create();
-               enumerator = this->sessions->create_enumerator(this->sessions);
-               while (enumerator->enumerate(enumerator, &sid, &entry))
-               {
-                       /* check all sessions for timeout or close flag */
-                       if (!entry->in_use &&
-                               (entry->used < now - this->timeout || entry->closed))
-                       {
-                               remove->insert_last(remove, sid);
-                       }
-               }
-               enumerator->destroy(enumerator);
-
-               while (remove->remove_last(remove, (void**)&sid) == SUCCESS)
-               {
-                       entry = this->sessions->remove(this->sessions, sid);
-                       if (entry)
-                       {
-                               session_entry_destroy(entry);
-                       }
-               }
-               remove->destroy(remove);
-       }
-}
-
-/**
- * Actual dispatching code
- */
-static void dispatch(private_dispatcher_t *this)
-{
-       thread_cancelability(FALSE);
-
-       while (TRUE)
-       {
-               request_t *request;
-               session_entry_t *found = NULL;
-               time_t now;
-               char *sid;
-
-               thread_cancelability(TRUE);
-               request = request_create(this->fd, this->debug);
-               thread_cancelability(FALSE);
-
-               if (request == NULL)
-               {
-                       continue;
-               }
-               now = time_monotonic(NULL);
-               sid = request->get_cookie(request, "SID");
-
-               this->mutex->lock(this->mutex);
-               if (sid)
-               {
-                       found = this->sessions->get(this->sessions, sid);
-               }
-               if (found && !streq(found->host, request->get_host(request)))
-               {
-                       found = NULL;
-               }
-               if (found)
-               {
-                       /* wait until session is unused */
-                       while (found->in_use)
-                       {
-                               found->cond->wait(found->cond, this->mutex);
-                       }
-               }
-               else
-               {       /* create a new session if not found */
-                       found = session_entry_create(this, request->get_host(request));
-                       if (!found)
-                       {
-                               request->destroy(request);
-                               this->mutex->unlock(this->mutex);
-                               continue;
-                       }
-                       sid = found->session->get_sid(found->session);
-                       this->sessions->put(this->sessions, sid, found);
-               }
-               found->in_use = TRUE;
-               this->mutex->unlock(this->mutex);
-
-               /* start processing */
-               found->session->process(found->session, request);
-               found->used = time_monotonic(NULL);
-
-               /* release session */
-               this->mutex->lock(this->mutex);
-               found->in_use = FALSE;
-               found->closed = request->session_closed(request);
-               found->cond->signal(found->cond);
-               cleanup_sessions(this, now);
-               this->mutex->unlock(this->mutex);
-
-               request->destroy(request);
-       }
-}
-
-METHOD(dispatcher_t, run, void,
-       private_dispatcher_t *this, int threads)
-{
-       this->thread_count = threads;
-       this->threads = malloc(sizeof(thread_t*) * threads);
-       while (threads)
-       {
-               this->threads[threads - 1] = thread_create((thread_main_t)dispatch,
-                                                                                                  this);
-               if (this->threads[threads - 1])
-               {
-                       threads--;
-               }
-       }
-}
-
-METHOD(dispatcher_t, waitsignal, void,
-       private_dispatcher_t *this)
-{
-       sigset_t set;
-       int sig;
-
-       sigemptyset(&set);
-       sigaddset(&set, SIGINT);
-       sigaddset(&set, SIGTERM);
-       sigaddset(&set, SIGHUP);
-       sigprocmask(SIG_BLOCK, &set, NULL);
-       sigwait(&set, &sig);
-}
-
-METHOD(dispatcher_t, destroy, void,
-       private_dispatcher_t *this)
-{
-       char *sid;
-       session_entry_t *entry;
-       enumerator_t *enumerator;
-
-       FCGX_ShutdownPending();
-       while (this->thread_count--)
-       {
-               thread_t *thread = this->threads[this->thread_count];
-               thread->cancel(thread);
-               thread->join(thread);
-       }
-       enumerator = this->sessions->create_enumerator(this->sessions);
-       while (enumerator->enumerate(enumerator, &sid, &entry))
-       {
-               session_entry_destroy(entry);
-       }
-       enumerator->destroy(enumerator);
-       this->sessions->destroy(this->sessions);
-       this->controllers->destroy_function(this->controllers, free);
-       this->filters->destroy_function(this->filters, free);
-       this->mutex->destroy(this->mutex);
-       free(this->threads);
-       free(this);
-}
-
-/*
- * see header file
- */
-dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
-                                                               context_constructor_t constructor, void *param)
-{
-       private_dispatcher_t *this;
-
-       INIT(this,
-               .public = {
-                       .add_controller = _add_controller,
-                       .add_filter = _add_filter,
-                       .run = _run,
-                       .waitsignal = _waitsignal,
-                       .destroy = _destroy,
-               },
-               .sessions = hashtable_create((void*)session_hash,
-                                                                        (void*)session_equals, 4096),
-               .controllers = linked_list_create(),
-               .filters = linked_list_create(),
-               .context_constructor = constructor,
-               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
-               .param = param,
-               .timeout = timeout,
-               .last_cleanup = time_monotonic(NULL),
-               .debug = debug,
-       );
-
-       FCGX_Init();
-
-       if (socket)
-       {
-               unlink(socket);
-               this->fd = FCGX_OpenSocket(socket, 10);
-       }
-       return &this->public;
-}
-
diff --git a/src/libfast/dispatcher.h b/src/libfast/dispatcher.h
deleted file mode 100644 (file)
index 16223fe..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup libfast libfast
- * @{
- * FastCGI Application Server w/ templates.
- *
- * Libfast is a framework to write web applications in an MVC fashion. It uses
- * the ClearSilver template engine and communicates through FastCGI with
- * the webserver. It is multithreaded and really fast.
- *
- * The application has a global context and a session context. The global
- * context is accessed from all sessions simultaneously and therefore
- * needs to be threadsave. Often a database wrapper is the global context.
- * The session context is instanciated per session. Sessions are managed
- * automatically through session cookies. The session context is kept alive
- * until the session times out. It must implement the context_t interface and
- * a #context_constructor_t is needed to create instances. To each session,
- * a set of controllers gets instanciated. The controller instances are per
- * session, so you can hold private data for each user.
- * Controllers need to implement the controller_t interface and need a
- * #controller_constructor_t function to create instances.
- *
- * A small example shows how to set up libfast:
- * @code
-       dispatcher_t *dispatcher;
-       your_global_context_implementation_t *global;
-
-       global = initialize_your_global_context();
-
-       dispatcher = dispatcher_create(NULL, FALSE, 180,
-                       (context_constructor_t)your_session_context_create, global);
-       dispatcher->add_controller(dispatcher, your_controller1_create, param1);
-       dispatcher->add_controller(dispatcher, your_controller2_create, param2);
-
-       dispatcher->run(dispatcher, 20);
-
-       dispatcher->waitsignal(dispatcher);
-
-       dispatcher->destroy(dispatcher);
-       global->destroy();
-   @endcode
- * @}
- *
- * @defgroup dispatcher dispatcher
- * @{ @ingroup libfast
- */
-
-#ifndef DISPATCHER_H_
-#define DISPATCHER_H_
-
-#include "controller.h"
-#include "filter.h"
-
-typedef struct dispatcher_t dispatcher_t;
-
-/**
- * Dispatcher, accepts connections using multiple threads.
- *
- * The dispatcher creates a session for each client (using SID cookies). In
- * each session, a session context is created using the context constructor.
- * Each controller is instanciated in the session using the controller
- * constructor added with add_controller.
- */
-struct dispatcher_t {
-
-       /**
-        * Register a controller to the dispatcher.
-        *
-        * The first controller added serves as default controller. Client's
-        * get redirected to it if no other controller matches.
-        *
-        * @param constructor   constructor function to the conntroller
-        * @param param                 param to pass to constructor
-        */
-       void (*add_controller)(dispatcher_t *this,
-                                                  controller_constructor_t constructor, void *param);
-
-       /**
-        * Add a filter to the dispatcher.
-        *
-        * @param constructor   constructor to create filter in session
-        * @param param                 param to pass to constructor
-        */
-       void (*add_filter)(dispatcher_t *this,
-                                          filter_constructor_t constructor, void *param);
-
-       /**
-        * Start with dispatching.
-        *
-        * Instanciate a constant thread pool and start dispatching requests.
-        *
-        * @param threads               number of dispatching threads
-        */
-       void (*run)(dispatcher_t *this, int threads);
-
-       /**
-        * Wait for a relevant signal action.
-        *
-        */
-       void (*waitsignal)(dispatcher_t *this);
-
-       /**
-        * Destroy the dispatcher_t.
-        */
-       void (*destroy) (dispatcher_t *this);
-};
-
-/**
- * Create a dispatcher.
- *
- * The context constructor is invoked to create a session context for
- * each session.
- *
- * @param socket               FastCGI socket path, NULL for dynamic
- * @param debug                        no stripping, no compression, timing information
- * @param timeout              session timeout
- * @param constructor  construction function for session context
- * @param param                        parameter to supply to context constructor
- */
-dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
-                                                               context_constructor_t constructor, void *param);
-
-#endif /** DISPATCHER_H_ @}*/
diff --git a/src/libfast/fast_context.h b/src/libfast/fast_context.h
new file mode 100644 (file)
index 0000000..4922703
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fast_context fast_context
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_CONTEXT_H_
+#define FAST_CONTEXT_H_
+
+typedef struct fast_context_t fast_context_t;
+
+/**
+ * Constructor function for a user specific context.
+ */
+typedef fast_context_t *(*fast_context_constructor_t)(void *param);
+
+/**
+ * User specific session context, to extend.
+ */
+struct fast_context_t {
+
+       /**
+        * Destroy the fast_context_t.
+        */
+       void (*destroy) (fast_context_t *this);
+};
+
+#endif /** FAST_CONTEXT_H_ @}*/
diff --git a/src/libfast/fast_controller.h b/src/libfast/fast_controller.h
new file mode 100644 (file)
index 0000000..bbd0214
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fast_controller fast_controller
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_CONTROLLER_H_
+#define FAST_CONTROLLER_H_
+
+#include "fast_request.h"
+#include "fast_context.h"
+
+typedef struct fast_controller_t fast_controller_t;
+
+/**
+ * Constructor function for a controller.
+ *
+ * @param context              session specific context, implements context_t
+ * @param param                        user supplied param, as registered to the dispatcher
+ */
+typedef fast_controller_t *(*fast_controller_constructor_t)(
+                                                                               fast_context_t* context, void *param);
+
+/**
+ * Controller interface, to be implemented by users controllers.
+ *
+ * Controller instances get created per session, so each session has an
+ * associated set of private controller instances.
+ * The controller handle function is called for each incoming request.
+ */
+struct fast_controller_t {
+
+       /**
+        * Get the name of the controller.
+        *
+        * @return                              name of the controller
+        */
+       char* (*get_name)(fast_controller_t *this);
+
+       /**
+        * Handle a HTTP request for that controller.
+        *
+        * Request URLs are parsed in the form
+        * controller_name/p1/p2/p3/p4/p5 with a maximum of 5 parameters. Each
+        * parameter not found in the request URL is set to NULL.
+        *
+        * @param request               HTTP request
+        * @param p1                    first parameter
+        * @param p2                    second parameter
+        * @param p3                    third parameter
+        * @param p4                    forth parameter
+        * @param p5                    fifth parameter
+        * @return
+        */
+       void (*handle)(fast_controller_t *this, fast_request_t *request,
+                                  char *p1, char *p2, char *p3, char *p4, char *p5);
+
+       /**
+        * Destroy the controller instance.
+        */
+       void (*destroy) (fast_controller_t *this);
+};
+
+#endif /** FAST_CONTROLLER_H_ @}*/
diff --git a/src/libfast/fast_dispatcher.c b/src/libfast/fast_dispatcher.c
new file mode 100644 (file)
index 0000000..e0c57b4
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * 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 "fast_dispatcher.h"
+
+#include "fast_request.h"
+#include "fast_session.h"
+
+#include <fcgiapp.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <utils/debug.h>
+#include <threading/thread.h>
+#include <threading/condvar.h>
+#include <threading/mutex.h>
+#include <collections/linked_list.h>
+#include <collections/hashtable.h>
+
+/** Intervall to check for expired sessions, in seconds */
+#define CLEANUP_INTERVAL 30
+
+typedef struct private_fast_dispatcher_t private_fast_dispatcher_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_fast_dispatcher_t {
+
+       /**
+        * public functions
+        */
+       fast_dispatcher_t public;
+
+       /**
+        * fcgi socket fd
+        */
+       int fd;
+
+       /**
+        * thread list
+        */
+       thread_t **threads;
+
+       /**
+        * number of threads in "threads"
+        */
+       int thread_count;
+
+       /**
+        * session locking mutex
+        */
+       mutex_t *mutex;
+
+       /**
+        * Hahstable with active sessions
+        */
+       hashtable_t *sessions;
+
+       /**
+        * session timeout
+        */
+       time_t timeout;
+
+       /**
+        * timestamp of last session cleanup round
+        */
+       time_t last_cleanup;
+
+       /**
+        * running in debug mode?
+        */
+       bool debug;
+
+       /**
+        * List of controllers controller_constructor_t
+        */
+       linked_list_t *controllers;
+
+       /**
+        * List of filters filter_constructor_t
+        */
+       linked_list_t *filters;
+
+       /**
+        * constructor function to create session context (in controller_entry_t)
+        */
+       fast_context_constructor_t context_constructor;
+
+       /**
+        * user param to context constructor
+        */
+       void *param;
+};
+
+typedef struct {
+       /** constructor function */
+       fast_controller_constructor_t constructor;
+       /** parameter to constructor */
+       void *param;
+} controller_entry_t;
+
+typedef struct {
+       /** constructor function */
+       fast_filter_constructor_t constructor;
+       /** parameter to constructor */
+       void *param;
+} filter_entry_t;
+
+typedef struct {
+       /** session instance */
+       fast_session_t *session;
+       /** condvar to wait for session */
+       condvar_t *cond;
+       /** client host address, to prevent session hijacking */
+       char *host;
+       /** TRUE if session is in use */
+       bool in_use;
+       /** last use of the session */
+       time_t used;
+       /** has the session been closed by the handler? */
+       bool closed;
+} session_entry_t;
+
+/**
+ * create a session and instanciate controllers
+ */
+static fast_session_t* load_session(private_fast_dispatcher_t *this)
+{
+       enumerator_t *enumerator;
+       controller_entry_t *centry;
+       filter_entry_t *fentry;
+       fast_session_t *session;
+       fast_context_t *context = NULL;
+       fast_controller_t *controller;
+       fast_filter_t *filter;
+
+       if (this->context_constructor)
+       {
+               context = this->context_constructor(this->param);
+       }
+       session = fast_session_create(context);
+
+       enumerator = this->controllers->create_enumerator(this->controllers);
+       while (enumerator->enumerate(enumerator, &centry))
+       {
+               controller = centry->constructor(context, centry->param);
+               session->add_controller(session, controller);
+       }
+       enumerator->destroy(enumerator);
+
+       enumerator = this->filters->create_enumerator(this->filters);
+       while (enumerator->enumerate(enumerator, &fentry))
+       {
+               filter = fentry->constructor(context, fentry->param);
+               session->add_filter(session, filter);
+       }
+       enumerator->destroy(enumerator);
+
+       return session;
+}
+
+/**
+ * create a new session entry
+ */
+static session_entry_t *session_entry_create(private_fast_dispatcher_t *this,
+                                                                                        char *host)
+{
+       session_entry_t *entry;
+       fast_session_t *session;
+
+       session = load_session(this);
+       if (!session)
+       {
+               return NULL;
+       }
+       INIT(entry,
+               .cond = condvar_create(CONDVAR_TYPE_DEFAULT),
+               .session = session,
+               .host = strdup(host),
+               .used = time_monotonic(NULL),
+       );
+       return entry;
+}
+
+/**
+ * destroy a session
+ */
+static void session_entry_destroy(session_entry_t *entry)
+{
+       entry->session->destroy(entry->session);
+       entry->cond->destroy(entry->cond);
+       free(entry->host);
+       free(entry);
+}
+
+METHOD(fast_dispatcher_t, add_controller, void,
+       private_fast_dispatcher_t *this, fast_controller_constructor_t constructor,
+       void *param)
+{
+       controller_entry_t *entry;
+
+       INIT(entry,
+               .constructor = constructor,
+               .param = param,
+       );
+       this->controllers->insert_last(this->controllers, entry);
+}
+
+METHOD(fast_dispatcher_t, add_filter, void,
+       private_fast_dispatcher_t *this, fast_filter_constructor_t constructor,
+       void *param)
+{
+       filter_entry_t *entry;
+
+       INIT(entry,
+               .constructor = constructor,
+               .param = param,
+       );
+       this->filters->insert_last(this->filters, entry);
+}
+
+/**
+ * Hashtable hash function
+ */
+static u_int session_hash(char *sid)
+{
+       return chunk_hash(chunk_create(sid, strlen(sid)));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool session_equals(char *sid1, char *sid2)
+{
+       return streq(sid1, sid2);
+}
+
+/**
+ * Cleanup unused sessions
+ */
+static void cleanup_sessions(private_fast_dispatcher_t *this, time_t now)
+{
+       if (this->last_cleanup < now - CLEANUP_INTERVAL)
+       {
+               char *sid;
+               session_entry_t *entry;
+               enumerator_t *enumerator;
+               linked_list_t *remove;
+
+               this->last_cleanup = now;
+               remove = linked_list_create();
+               enumerator = this->sessions->create_enumerator(this->sessions);
+               while (enumerator->enumerate(enumerator, &sid, &entry))
+               {
+                       /* check all sessions for timeout or close flag */
+                       if (!entry->in_use &&
+                               (entry->used < now - this->timeout || entry->closed))
+                       {
+                               remove->insert_last(remove, sid);
+                       }
+               }
+               enumerator->destroy(enumerator);
+
+               while (remove->remove_last(remove, (void**)&sid) == SUCCESS)
+               {
+                       entry = this->sessions->remove(this->sessions, sid);
+                       if (entry)
+                       {
+                               session_entry_destroy(entry);
+                       }
+               }
+               remove->destroy(remove);
+       }
+}
+
+/**
+ * Actual dispatching code
+ */
+static void dispatch(private_fast_dispatcher_t *this)
+{
+       thread_cancelability(FALSE);
+
+       while (TRUE)
+       {
+               fast_request_t *request;
+               session_entry_t *found = NULL;
+               time_t now;
+               char *sid;
+
+               thread_cancelability(TRUE);
+               request = fast_request_create(this->fd, this->debug);
+               thread_cancelability(FALSE);
+
+               if (request == NULL)
+               {
+                       continue;
+               }
+               now = time_monotonic(NULL);
+               sid = request->get_cookie(request, "SID");
+
+               this->mutex->lock(this->mutex);
+               if (sid)
+               {
+                       found = this->sessions->get(this->sessions, sid);
+               }
+               if (found && !streq(found->host, request->get_host(request)))
+               {
+                       found = NULL;
+               }
+               if (found)
+               {
+                       /* wait until session is unused */
+                       while (found->in_use)
+                       {
+                               found->cond->wait(found->cond, this->mutex);
+                       }
+               }
+               else
+               {       /* create a new session if not found */
+                       found = session_entry_create(this, request->get_host(request));
+                       if (!found)
+                       {
+                               request->destroy(request);
+                               this->mutex->unlock(this->mutex);
+                               continue;
+                       }
+                       sid = found->session->get_sid(found->session);
+                       this->sessions->put(this->sessions, sid, found);
+               }
+               found->in_use = TRUE;
+               this->mutex->unlock(this->mutex);
+
+               /* start processing */
+               found->session->process(found->session, request);
+               found->used = time_monotonic(NULL);
+
+               /* release session */
+               this->mutex->lock(this->mutex);
+               found->in_use = FALSE;
+               found->closed = request->session_closed(request);
+               found->cond->signal(found->cond);
+               cleanup_sessions(this, now);
+               this->mutex->unlock(this->mutex);
+
+               request->destroy(request);
+       }
+}
+
+METHOD(fast_dispatcher_t, run, void,
+       private_fast_dispatcher_t *this, int threads)
+{
+       this->thread_count = threads;
+       this->threads = malloc(sizeof(thread_t*) * threads);
+       while (threads)
+       {
+               this->threads[threads - 1] = thread_create((thread_main_t)dispatch,
+                                                                                                  this);
+               if (this->threads[threads - 1])
+               {
+                       threads--;
+               }
+       }
+}
+
+METHOD(fast_dispatcher_t, waitsignal, void,
+       private_fast_dispatcher_t *this)
+{
+       sigset_t set;
+       int sig;
+
+       sigemptyset(&set);
+       sigaddset(&set, SIGINT);
+       sigaddset(&set, SIGTERM);
+       sigaddset(&set, SIGHUP);
+       sigprocmask(SIG_BLOCK, &set, NULL);
+       sigwait(&set, &sig);
+}
+
+METHOD(fast_dispatcher_t, destroy, void,
+       private_fast_dispatcher_t *this)
+{
+       char *sid;
+       session_entry_t *entry;
+       enumerator_t *enumerator;
+
+       FCGX_ShutdownPending();
+       while (this->thread_count--)
+       {
+               thread_t *thread = this->threads[this->thread_count];
+               thread->cancel(thread);
+               thread->join(thread);
+       }
+       enumerator = this->sessions->create_enumerator(this->sessions);
+       while (enumerator->enumerate(enumerator, &sid, &entry))
+       {
+               session_entry_destroy(entry);
+       }
+       enumerator->destroy(enumerator);
+       this->sessions->destroy(this->sessions);
+       this->controllers->destroy_function(this->controllers, free);
+       this->filters->destroy_function(this->filters, free);
+       this->mutex->destroy(this->mutex);
+       free(this->threads);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+fast_dispatcher_t *fast_dispatcher_create(char *socket, bool debug, int timeout,
+                                                       fast_context_constructor_t constructor, void *param)
+{
+       private_fast_dispatcher_t *this;
+
+       INIT(this,
+               .public = {
+                       .add_controller = _add_controller,
+                       .add_filter = _add_filter,
+                       .run = _run,
+                       .waitsignal = _waitsignal,
+                       .destroy = _destroy,
+               },
+               .sessions = hashtable_create((void*)session_hash,
+                                                                        (void*)session_equals, 4096),
+               .controllers = linked_list_create(),
+               .filters = linked_list_create(),
+               .context_constructor = constructor,
+               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+               .param = param,
+               .timeout = timeout,
+               .last_cleanup = time_monotonic(NULL),
+               .debug = debug,
+       );
+
+       FCGX_Init();
+
+       if (socket)
+       {
+               unlink(socket);
+               this->fd = FCGX_OpenSocket(socket, 10);
+       }
+       return &this->public;
+}
diff --git a/src/libfast/fast_dispatcher.h b/src/libfast/fast_dispatcher.h
new file mode 100644 (file)
index 0000000..6546385
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup libfast libfast
+ * @{
+ * FastCGI Application Server w/ templates.
+ *
+ * Libfast is a framework to write web applications in an MVC fashion. It uses
+ * the ClearSilver template engine and communicates through FastCGI with
+ * the webserver. It is multithreaded and really fast.
+ *
+ * The application has a global context and a session context. The global
+ * context is accessed from all sessions simultaneously and therefore
+ * needs to be threadsave. Often a database wrapper is the global context.
+ * The session context is instanciated per session. Sessions are managed
+ * automatically through session cookies. The session context is kept alive
+ * until the session times out. It must implement the context_t interface and
+ * a #fast_context_constructor_t is needed to create instances. To each session,
+ * a set of controllers gets instanciated. The controller instances are per
+ * session, so you can hold private data for each user.
+ * Controllers need to implement the controller_t interface and need a
+ * #fast_controller_constructor_t function to create instances.
+ *
+ * A small example shows how to set up libfast:
+ * @code
+       fast_fast_dispatcher_t *dispatcher;
+       your_global_context_implementation_t *global;
+
+       global = initialize_your_global_context();
+
+       dispatcher = fast_dispatcher_create(NULL, FALSE, 180,
+                       (context_constructor_t)your_session_context_create, global);
+       dispatcher->add_controller(dispatcher, your_controller1_create, param1);
+       dispatcher->add_controller(dispatcher, your_controller2_create, param2);
+
+       dispatcher->run(dispatcher, 20);
+
+       dispatcher->waitsignal(dispatcher);
+
+       dispatcher->destroy(dispatcher);
+       global->destroy();
+   @endcode
+ * @}
+ *
+ * @defgroup fast_dispatcher fast_dispatcher
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_DISPATCHER_H_
+#define FAST_DISPATCHER_H_
+
+#include "fast_controller.h"
+#include "fast_filter.h"
+
+typedef struct fast_dispatcher_t fast_dispatcher_t;
+
+/**
+ * Dispatcher, accepts connections using multiple threads.
+ *
+ * The dispatcher creates a session for each client (using SID cookies). In
+ * each session, a session context is created using the context constructor.
+ * Each controller is instanciated in the session using the controller
+ * constructor added with add_controller.
+ */
+struct fast_dispatcher_t {
+
+       /**
+        * Register a controller to the dispatcher.
+        *
+        * The first controller added serves as default controller. Client's
+        * get redirected to it if no other controller matches.
+        *
+        * @param constructor   constructor function to the conntroller
+        * @param param                 param to pass to constructor
+        */
+       void (*add_controller)(fast_dispatcher_t *this,
+                                                  fast_controller_constructor_t constructor,
+                                                  void *param);
+
+       /**
+        * Add a filter to the dispatcher.
+        *
+        * @param constructor   constructor to create filter in session
+        * @param param                 param to pass to constructor
+        */
+       void (*add_filter)(fast_dispatcher_t *this,
+                                          fast_filter_constructor_t constructor, void *param);
+
+       /**
+        * Start with dispatching.
+        *
+        * Instanciate a constant thread pool and start dispatching requests.
+        *
+        * @param threads               number of dispatching threads
+        */
+       void (*run)(fast_dispatcher_t *this, int threads);
+
+       /**
+        * Wait for a relevant signal action.
+        */
+       void (*waitsignal)(fast_dispatcher_t *this);
+
+       /**
+        * Destroy the fast_dispatcher_t.
+        */
+       void (*destroy) (fast_dispatcher_t *this);
+};
+
+/**
+ * Create a dispatcher.
+ *
+ * The context constructor is invoked to create a session context for
+ * each session.
+ *
+ * @param socket               FastCGI socket path, NULL for dynamic
+ * @param debug                        no stripping, no compression, timing information
+ * @param timeout              session timeout
+ * @param constructor  construction function for session context
+ * @param param                        parameter to supply to context constructor
+ */
+fast_dispatcher_t *fast_dispatcher_create(char *socket, bool debug, int timeout,
+                                                       fast_context_constructor_t constructor, void *param);
+
+#endif /** FAST_DISPATCHER_H_ @}*/
diff --git a/src/libfast/fast_filter.h b/src/libfast/fast_filter.h
new file mode 100644 (file)
index 0000000..57367bd
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/*
+ * @defgroup fast_filter fast_filter
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_FILTER_H_
+#define FAST_FILTER_H_
+
+#include "fast_request.h"
+#include "fast_context.h"
+#include "fast_controller.h"
+
+typedef struct fast_filter_t fast_filter_t;
+
+/**
+ * Constructor function for a filter
+ *
+ * @param context              session specific context
+ * @param param                        user supplied param
+ */
+typedef fast_filter_t *(*fast_filter_constructor_t)(fast_context_t* context,
+                                                                                                       void *param);
+
+/**
+ * Filter interface, to be implemented by users filters.
+ */
+struct fast_filter_t {
+
+       /**
+        * Called before the controller handles the request.
+        *
+        * @param request               HTTP request
+        * @param p1                    first parameter
+        * @param p2                    second parameter
+        * @param p3                    third parameter
+        * @param p4                    forth parameter
+        * @param p5                    fifth parameter
+        * @return                              TRUE to continue request handling
+        */
+       bool (*run)(fast_filter_t *this, fast_request_t *request,
+                               char *p0, char *p1, char *p2, char *p3, char *p4, char *p5);
+
+       /**
+        * Destroy the filter instance.
+        */
+       void (*destroy) (fast_filter_t *this);
+};
+
+#endif /* FAST_FILTER_H_ @} */
diff --git a/src/libfast/fast_request.c b/src/libfast/fast_request.c
new file mode 100644 (file)
index 0000000..0673750
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#include "fast_request.h"
+
+#include <library.h>
+#include <utils/debug.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <ClearSilver/ClearSilver.h>
+
+#include <threading/thread.h>
+#include <threading/thread_value.h>
+
+typedef struct private_fast_request_t private_fast_request_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_fast_request_t {
+
+       /**
+        * public functions
+        */
+       fast_request_t public;
+
+       /**
+        * FastCGI request object
+        */
+       FCGX_Request req;
+
+       /**
+        * length of the req.envp array
+        */
+       int req_env_len;
+
+       /**
+        * ClearSilver CGI Kit context
+        */
+       CGI *cgi;
+
+       /**
+        * ClearSilver HDF dataset for this request
+        */
+       HDF *hdf;
+
+       /**
+        * close the session?
+        */
+       bool closed;
+
+       /**
+        * reference count
+        */
+       refcount_t ref;
+};
+
+/**
+ * ClearSilver cgiwrap is not threadsave, so we use a private
+ * context for each thread.
+ */
+static thread_value_t *thread_this;
+
+/**
+ * control variable for pthread_once
+ */
+pthread_once_t once = PTHREAD_ONCE_INIT;
+
+/**
+ * fcgiwrap read callback
+ */
+static int read_cb(void *null, char *buf, int size)
+{
+       private_fast_request_t *this;
+
+       this = (private_fast_request_t*)thread_this->get(thread_this);
+
+       return FCGX_GetStr(buf, size, this->req.in);
+}
+
+/**
+ * fcgiwrap writef callback
+ */
+static int writef_cb(void *null, const char *format, va_list args)
+{
+       private_fast_request_t *this;
+
+       this = (private_fast_request_t*)thread_this->get(thread_this);
+
+       FCGX_VFPrintF(this->req.out, format, args);
+       return 0;
+}
+/**
+ * fcgiwrap write callback
+ */
+static int write_cb(void *null, const char *buf, int size)
+{
+       private_fast_request_t *this;
+
+       this = (private_fast_request_t*)thread_this->get(thread_this);
+
+       return FCGX_PutStr(buf, size, this->req.out);
+}
+
+/**
+ * fcgiwrap getenv callback
+ */
+static char *getenv_cb(void *null, const char *key)
+{
+       char *value;
+       private_fast_request_t *this;
+
+       this = (private_fast_request_t*)thread_this->get(thread_this);
+
+       value = FCGX_GetParam(key, this->req.envp);
+       return strdupnull(value);
+}
+
+/**
+ * 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)
+{
+       private_fast_request_t *this;
+
+       *key = NULL;
+       *value = NULL;
+       this = (private_fast_request_t*)thread_this->get(thread_this);
+
+       if (num < this->req_env_len)
+       {
+               char *eq;
+
+               eq = strchr(this->req.envp[num], '=');
+               if (eq)
+               {
+                       *key = strndup(this->req.envp[num], eq - this->req.envp[num]);
+                       *value = strdup(eq + 1);
+               }
+               if (*key == NULL || *value == NULL)
+               {
+                       free(*key);
+                       free(*value);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+METHOD(fast_request_t, get_cookie, char*,
+       private_fast_request_t *this, char *name)
+{
+       return hdf_get_valuef(this->hdf, "Cookie.%s", name);
+}
+
+METHOD(fast_request_t, get_path, char*,
+       private_fast_request_t *this)
+{
+       char *path = FCGX_GetParam("PATH_INFO", this->req.envp);
+       return path ? path : "";
+}
+
+METHOD(fast_request_t, get_host, char*,
+       private_fast_request_t *this)
+{
+       char *addr = FCGX_GetParam("REMOTE_ADDR", this->req.envp);
+       return addr ? addr : "";
+}
+
+METHOD(fast_request_t, get_user_agent, char*,
+       private_fast_request_t *this)
+{
+       char *agent = FCGX_GetParam("HTTP_USER_AGENT", this->req.envp);
+       return agent ? agent : "";
+}
+
+METHOD(fast_request_t, get_query_data, char*,
+       private_fast_request_t *this, char *name)
+{
+       return hdf_get_valuef(this->hdf, "Query.%s", name);
+}
+
+METHOD(fast_request_t, get_env_var, char*,
+       private_fast_request_t *this, char *name)
+{
+       return FCGX_GetParam(name, this->req.envp);
+}
+
+METHOD(fast_request_t, read_data, int,
+       private_fast_request_t *this, char *buf, int len)
+{
+       return FCGX_GetStr(buf, len, this->req.in);
+}
+
+METHOD(fast_request_t, get_base, char*,
+       private_fast_request_t *this)
+{
+       return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
+}
+
+METHOD(fast_request_t, add_cookie, void,
+       private_fast_request_t *this, char *name, char *value)
+{
+       thread_this->set(thread_this, this);
+       cgi_cookie_set(this->cgi, name, value, NULL, NULL, NULL, 0, 0);
+}
+
+METHOD(fast_request_t, redirect, void,
+       private_fast_request_t *this, char *fmt, ...)
+{
+       va_list args;
+
+       FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+       FCGX_FPrintF(this->req.out, "Location: %s%s", get_base(this),
+                                *fmt == '/' ? "" : "/");
+       va_start(args, fmt);
+       FCGX_VFPrintF(this->req.out, fmt, args);
+       va_end(args);
+       FCGX_FPrintF(this->req.out, "\n\n");
+}
+
+METHOD(fast_request_t, get_referer, char*,
+       private_fast_request_t *this)
+{
+       return FCGX_GetParam("HTTP_REFERER", this->req.envp);
+}
+
+METHOD(fast_request_t, to_referer, void,
+       private_fast_request_t *this)
+{
+       char *referer;
+
+       referer = get_referer(this);
+       if (referer)
+       {
+               FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+               FCGX_FPrintF(this->req.out, "Location: %s\n\n", referer);
+       }
+       else
+       {
+               redirect(this, "/");
+       }
+}
+
+METHOD(fast_request_t, session_closed, bool,
+       private_fast_request_t *this)
+{
+       return this->closed;
+}
+
+METHOD(fast_request_t, close_session, void,
+       private_fast_request_t *this)
+{
+       this->closed = TRUE;
+}
+
+METHOD(fast_request_t, serve, void,
+       private_fast_request_t *this, char *headers, chunk_t chunk)
+{
+       FCGX_FPrintF(this->req.out, "%s\n\n", headers);
+
+       FCGX_PutStr(chunk.ptr, chunk.len, this->req.out);
+}
+
+METHOD(fast_request_t, sendfile, bool,
+       private_fast_request_t *this, char *path, char *mime)
+{
+       struct stat sb;
+       chunk_t data;
+       void *addr;
+       int fd, written;
+       char buf[24];
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1)
+       {
+               return FALSE;
+       }
+       if (fstat(fd, &sb) == -1)
+       {
+               close(fd);
+               return FALSE;
+       }
+       addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (addr == MAP_FAILED)
+       {
+               close(fd);
+               return FALSE;
+       }
+
+       /* FCGX does not like large integers, print to a buffer using libc */
+       snprintf(buf, sizeof(buf), "%lld", (int64_t)sb.st_size);
+       FCGX_FPrintF(this->req.out, "Content-Length: %s\n", buf);
+       if (mime)
+       {
+               FCGX_FPrintF(this->req.out, "Content-Type: %s\n", mime);
+       }
+       FCGX_FPrintF(this->req.out, "\n");
+
+       data = chunk_create(addr, sb.st_size);
+
+       while (data.len)
+       {
+               written = FCGX_PutStr(data.ptr, data.len, this->req.out);
+               if (written == -1)
+               {
+                       munmap(addr, sb.st_size);
+                       close(fd);
+                       return FALSE;
+               }
+               data = chunk_skip(data, written);
+       }
+
+       munmap(addr, sb.st_size);
+       close(fd);
+       return TRUE;
+}
+
+METHOD(fast_request_t, render, void,
+       private_fast_request_t *this, char *template)
+{
+       NEOERR* err;
+
+       thread_this->set(thread_this, this);
+       err = cgi_display(this->cgi, template);
+       if (err)
+       {
+               cgi_neo_error(this->cgi, err);
+               nerr_log_error(err);
+       }
+}
+
+METHOD(fast_request_t, streamf, int,
+       private_fast_request_t *this, char *format, ...)
+{
+       va_list args;
+       int written;
+
+       va_start(args, format);
+       written = FCGX_VFPrintF(this->req.out, format, args);
+       va_end(args);
+       if (written >= 0 &&
+               FCGX_FFlush(this->req.out) == -1)
+       {
+               return -1;
+       }
+       return written;
+}
+
+METHOD(fast_request_t, set, void,
+       private_fast_request_t *this, char *key, char *value)
+{
+       hdf_set_value(this->hdf, key, value);
+}
+
+METHOD(fast_request_t, setf, void,
+       private_fast_request_t *this, char *format, ...)
+{
+       va_list args;
+
+       va_start(args, format);
+       hdf_set_valuevf(this->hdf, format, args);
+       va_end(args);
+}
+
+METHOD(fast_request_t, get_ref, fast_request_t*,
+       private_fast_request_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
+}
+
+METHOD(fast_request_t, destroy, void,
+       private_fast_request_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               thread_this->set(thread_this, this);
+               cgi_destroy(&this->cgi);
+               FCGX_Finish_r(&this->req);
+               free(this);
+       }
+}
+
+/**
+ * This initialization method is guaranteed to run only once
+ * for all threads.
+ */
+static void init(void)
+{
+       cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
+                                        getenv_cb, putenv_cb, iterenv_cb);
+       thread_this = thread_value_create(NULL);
+}
+
+/*
+ * see header file
+ */
+fast_request_t *fast_request_create(int fd, bool debug)
+{
+       NEOERR* err;
+       private_fast_request_t *this;
+       bool failed = FALSE;
+
+       INIT(this,
+               .public = {
+                       .get_path = _get_path,
+                       .get_base = _get_base,
+                       .get_host = _get_host,
+                       .get_user_agent = _get_user_agent,
+                       .add_cookie = _add_cookie,
+                       .get_cookie = _get_cookie,
+                       .get_query_data = _get_query_data,
+                       .get_env_var = _get_env_var,
+                       .read_data = _read_data,
+                       .session_closed = _session_closed,
+                       .close_session = _close_session,
+                       .redirect = _redirect,
+                       .get_referer = _get_referer,
+                       .to_referer = _to_referer,
+                       .render = _render,
+                       .streamf = _streamf,
+                       .serve = _serve,
+                       .sendfile = _sendfile,
+                       .set = _set,
+                       .setf = _setf,
+                       .get_ref = _get_ref,
+                       .destroy = _destroy,
+               },
+               .ref = 1,
+       );
+
+       thread_cleanup_push(free, this);
+       if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
+               FCGX_Accept_r(&this->req) != 0)
+       {
+               failed = TRUE;
+       }
+       thread_cleanup_pop(failed);
+       if (failed)
+       {
+               return NULL;
+       }
+
+       pthread_once(&once, init);
+       thread_this->set(thread_this, this);
+
+       while (this->req.envp[this->req_env_len] != NULL)
+       {
+               this->req_env_len++;
+       }
+
+       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");
+               }
+
+               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);
+       FCGX_Finish_r(&this->req);
+       free(this);
+       return NULL;
+}
diff --git a/src/libfast/fast_request.h b/src/libfast/fast_request.h
new file mode 100644 (file)
index 0000000..678cf54
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fast_request fast_request
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_REQUEST_H_
+#define FAST_REQUEST_H_
+
+#include <fcgiapp.h>
+#include <library.h>
+
+typedef struct fast_request_t fast_request_t;
+
+/**
+ * A HTTP request, encapsulates FCGX_Request.
+ *
+ * The response is also handled through the request object.
+ */
+struct fast_request_t {
+
+       /**
+        * 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)(fast_request_t *this, char *name, char *value);
+
+       /**
+        * Get a cookie the client sent in the request.
+        *
+        * @param name          name of the cookie
+        * @return                      cookie value, NULL if no such cookie found
+        */
+       char* (*get_cookie)(fast_request_t *this, char *name);
+
+       /**
+        * Get the request path relative to the application.
+        *
+        * @return                      path
+        */
+       char* (*get_path)(fast_request_t *this);
+
+       /**
+        * Get the base path of the application.
+        *
+        * @return                      base path
+        */
+       char* (*get_base)(fast_request_t *this);
+
+       /**
+        * Get the remote host address of this request.
+        *
+        * @return                      host address as string
+        */
+       char* (*get_host)(fast_request_t *this);
+
+       /**
+        * Get the user agent string.
+        *
+        * @return                      user agent string
+        */
+       char* (*get_user_agent)(fast_request_t *this);
+
+       /**
+        * 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_query_data)(fast_request_t *this, char *name);
+
+       /**
+        * Get an arbitrary environment variable.
+        *
+        * @param name          name of the environment variable
+        * @return                      value, NULL if not found
+        */
+       char* (*get_env_var)(fast_request_t *this, char *name);
+
+       /**
+        * Read raw POST/PUT data from HTTP request.
+        *
+        * @param buf           buffer to read data into
+        * @param len           size of the supplied buffer
+        * @return                      number of bytes read, < 0 on error
+        */
+       int (*read_data)(fast_request_t *this, char *buf, int len);
+
+       /**
+        * Close the session and it's context after handling.
+        */
+       void (*close_session)(fast_request_t *this);
+
+       /**
+        * Has the session been closed by close_session()?
+        *
+        * @return                      TRUE if session has been closed
+        */
+       bool (*session_closed)(fast_request_t *this);
+
+       /**
+        * Redirect the client to another location.
+        *
+        * @param fmt           location format string
+        * @param ...           variable argument for fmt
+        */
+       void (*redirect)(fast_request_t *this, char *fmt, ...);
+
+       /**
+        * Get the HTTP referer.
+        *
+        * @return                      HTTP referer
+        */
+       char* (*get_referer)(fast_request_t *this);
+
+       /**
+        * Redirect back to the referer.
+        */
+       void (*to_referer)(fast_request_t *this);
+
+       /**
+        * Set a template value.
+        *
+        * @param key           key to set
+        * @param value         value to set key to
+        */
+       void (*set)(fast_request_t *this, char *key, char *value);
+
+       /**
+        * 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)(fast_request_t *this, char *format, ...);
+
+       /**
+        * 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
+        */
+       void (*render)(fast_request_t *this, char *template);
+
+       /**
+        * Stream a format string to the client.
+        *
+        * Stream is not closed and may be called multiple times to allow
+        * server-push functionality.
+        *
+        * @param format        printf like format string
+        * @param ...           argmuent list to format string
+        * @return                      number of streamed bytes, < 0 if stream closed
+        */
+       int (*streamf)(fast_request_t *this, char *format, ...);
+
+       /**
+        * Serve a request with headers and a body.
+        *
+        * @param headers       HTTP headers, \n separated
+        * @param chunk         body to write to output
+        */
+       void (*serve)(fast_request_t *this, char *headers, chunk_t chunk);
+
+       /**
+        * Send a file from the file system.
+        *
+        * @param path          path to file to serve
+        * @param mime          mime type of file to send, or NULL
+        * @return                      TRUE if file served successfully
+        */
+       bool (*sendfile)(fast_request_t *this, char *path, char *mime);
+
+       /**
+        * Increase the reference count to the stream.
+        *
+        * @return                      this with increased refcount
+        */
+       fast_request_t* (*get_ref)(fast_request_t *this);
+
+       /**
+        * Destroy the fast_request_t.
+        */
+       void (*destroy) (fast_request_t *this);
+};
+
+/**
+ * Create a request from the fastcgi struct.
+ *
+ * @param fd                   file descripter opened with FCGX_OpenSocket
+ * @param debug                        no stripping, no compression, timing information
+ */
+fast_request_t *fast_request_create(int fd, bool debug);
+
+#endif /** REQUEST_H_ @}*/
diff --git a/src/libfast/fast_session.c b/src/libfast/fast_session.c
new file mode 100644 (file)
index 0000000..56d4a04
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#include "fast_session.h"
+
+#include <string.h>
+#include <fcgiapp.h>
+#include <stdio.h>
+
+#include <collections/linked_list.h>
+
+#define COOKIE_LEN 16
+
+typedef struct private_fast_session_t private_fast_session_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_fast_session_t {
+
+       /**
+        * public functions
+        */
+       fast_session_t public;
+
+       /**
+        * session ID
+        */
+       char sid[COOKIE_LEN * 2 + 1];
+
+       /**
+        * have we sent the session cookie?
+        */
+       bool cookie_sent;
+
+       /**
+        * list of controller instances controller_t
+        */
+       linked_list_t *controllers;
+
+       /**
+        * list of filter instances filter_t
+        */
+       linked_list_t *filters;
+
+       /**
+        * user defined session context
+        */
+       fast_context_t *context;
+};
+
+METHOD(fast_session_t, add_controller, void,
+       private_fast_session_t *this, fast_controller_t *controller)
+{
+       this->controllers->insert_last(this->controllers, controller);
+}
+
+METHOD(fast_session_t, add_filter, void,
+       private_fast_session_t *this, fast_filter_t *filter)
+{
+       this->filters->insert_last(this->filters, filter);
+}
+
+/**
+ * Create a session ID and a cookie
+ */
+static bool create_sid(private_fast_session_t *this)
+{
+       char buf[COOKIE_LEN];
+       rng_t *rng;
+
+       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+       if (!rng)
+       {
+               return FALSE;
+       }
+       if (!rng->get_bytes(rng, sizeof(buf), buf))
+       {
+               rng->destroy(rng);
+               return FALSE;
+       }
+       rng->destroy(rng);
+       chunk_to_hex(chunk_create(buf, sizeof(buf)), this->sid, FALSE);
+       return TRUE;
+}
+
+/**
+ * run all registered filters
+ */
+static bool run_filter(private_fast_session_t *this, fast_request_t *request,
+                                       char *p0, char *p1, char *p2, char *p3, char *p4, char *p5)
+{
+       enumerator_t *enumerator;
+       fast_filter_t *filter;
+
+       enumerator = this->filters->create_enumerator(this->filters);
+       while (enumerator->enumerate(enumerator, &filter))
+       {
+               if (!filter->run(filter, request, p0, p1, p2, p3, p4, p5))
+               {
+                       enumerator->destroy(enumerator);
+                       return FALSE;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return TRUE;
+}
+
+METHOD(fast_session_t, process, void,
+       private_fast_session_t *this, fast_request_t *request)
+{
+       char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
+       enumerator_t *enumerator;
+       bool handled = FALSE;
+       fast_controller_t *current;
+       int i = 0;
+
+       if (!this->cookie_sent)
+       {
+               request->add_cookie(request, "SID", this->sid);
+               this->cookie_sent = TRUE;
+       }
+
+       start = request->get_path(request);
+       if (start)
+       {
+               if (*start == '/')
+               {
+                       start++;
+               }
+               while ((pos = strchr(start, '/')) != NULL && i < 5)
+               {
+                       param[i++] = strndupa(start, pos - start);
+                       start = pos + 1;
+               }
+               param[i] = strdupa(start);
+
+               if (run_filter(this, request, param[0], param[1], param[2], param[3],
+                                               param[4], param[5]))
+               {
+                       enumerator = this->controllers->create_enumerator(this->controllers);
+                       while (enumerator->enumerate(enumerator, &current))
+                       {
+                               if (streq(current->get_name(current), param[0]))
+                               {
+                                       current->handle(current, request, param[1], param[2],
+                                                                       param[3], param[4], param[5]);
+                                       handled = TRUE;
+                                       break;
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+               }
+               else
+               {
+                       handled = TRUE;
+               }
+       }
+       if (!handled)
+       {
+               if (this->controllers->get_first(this->controllers,
+                                                                                (void**)&current) == SUCCESS)
+               {
+                       request->streamf(request,
+                               "Status: 301 Moved permanently\nLocation: %s/%s\n\n",
+                               request->get_base(request), current->get_name(current));
+               }
+       }
+}
+
+METHOD(fast_session_t, get_sid, char*,
+       private_fast_session_t *this)
+{
+       return this->sid;
+}
+
+METHOD(fast_session_t, destroy, void,
+       private_fast_session_t *this)
+{
+       this->controllers->destroy_offset(this->controllers,
+                                                                         offsetof(fast_controller_t, destroy));
+       this->filters->destroy_offset(this->filters,
+                                                                         offsetof(fast_filter_t, destroy));
+       DESTROY_IF(this->context);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+fast_session_t *fast_session_create(fast_context_t *context)
+{
+       private_fast_session_t *this;
+
+       INIT(this,
+               .public = {
+                       .add_controller = _add_controller,
+                       .add_filter = _add_filter,
+                       .process = _process,
+                       .get_sid = _get_sid,
+                       .destroy = _destroy,
+               },
+               .controllers = linked_list_create(),
+               .filters = linked_list_create(),
+               .context = context,
+       );
+       if (!create_sid(this))
+       {
+               destroy(this);
+               return NULL;
+       }
+
+       return &this->public;
+}
diff --git a/src/libfast/fast_session.h b/src/libfast/fast_session.h
new file mode 100644 (file)
index 0000000..2ff450b
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup fast_session fast_session
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_SESSION_H_
+#define FAST_SESSION_H_
+
+#include "fast_request.h"
+#include "fast_controller.h"
+#include "fast_filter.h"
+
+typedef struct fast_session_t fast_session_t;
+
+/**
+ * Session handling class, instanciated for each user session.
+ */
+struct fast_session_t {
+
+       /**
+        * Get the session ID of the session.
+        *
+        * @return                              session ID
+        */
+       char* (*get_sid)(fast_session_t *this);
+
+       /**
+        * Add a controller instance to the session.
+        *
+        * @param controller    controller to add
+        */
+       void (*add_controller)(fast_session_t *this, fast_controller_t *controller);
+
+       /**
+        * Add a filter instance to the session.
+        *
+        * @param filter                filter to add
+        */
+       void (*add_filter)(fast_session_t *this, fast_filter_t *filter);
+
+       /**
+        * Process a request in this session.
+        *
+        * @param request               request to process
+        */
+       void (*process)(fast_session_t *this, fast_request_t *request);
+
+       /**
+        * Destroy the fast_session_t.
+        */
+       void (*destroy) (fast_session_t *this);
+};
+
+/**
+ * Create a session new session.
+ *
+ * @param context              user defined session context instance
+ * @return                             client session, NULL on error
+ */
+fast_session_t *fast_session_create(fast_context_t *context);
+
+#endif /** SESSION_H_ @}*/
diff --git a/src/libfast/fast_smtp.c b/src/libfast/fast_smtp.c
new file mode 100644 (file)
index 0000000..89e74d7
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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 "fast_smtp.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <utils/debug.h>
+
+typedef struct private_fast_smtp_t private_fast_smtp_t;
+
+/**
+ * Private data of an fast_smtp_t object.
+ */
+struct private_fast_smtp_t {
+
+       /**
+        * Public fast_smtp_t interface.
+        */
+       fast_smtp_t public;
+
+       /**
+        * file stream to SMTP server
+        */
+       FILE *f;
+};
+
+/**
+ * Read the response code from an SMTP server
+ */
+static int read_response(private_fast_smtp_t *this)
+{
+       char buf[256], *end;
+       int res = 0;
+
+       while (TRUE)
+       {
+               if (!fgets(buf, sizeof(buf), this->f))
+               {
+                       return 0;
+               }
+               res = strtol(buf, &end, 10);
+               switch (*end)
+               {
+                       case '-':
+                               continue;
+                       case ' ':
+                       case '\0':
+                       case '\n':
+                               break;
+                       default:
+                               return 0;
+               }
+               break;
+       }
+       return res;
+}
+
+/**
+ * write a SMTP command to the server, read response code
+ */
+static int write_cmd(private_fast_smtp_t *this, char *fmt, ...)
+{
+       char buf[256];
+       va_list args;
+
+       va_start(args, fmt);
+       vsnprintf(buf, sizeof(buf), fmt, args);
+       va_end(args);
+
+       if (fprintf(this->f, "%s\n", buf) < 1)
+       {
+               DBG1(DBG_LIB, "sending SMTP command failed");
+               return 0;
+       }
+       return read_response(this);
+}
+
+METHOD(fast_smtp_t, send_mail, bool,
+       private_fast_smtp_t *this, char *from, char *to, char *subject, char *fmt, ...)
+{
+       va_list args;
+
+       if (write_cmd(this, "MAIL FROM:<%s>", from) != 250)
+       {
+               DBG1(DBG_LIB, "SMTP MAIL FROM failed");
+               return FALSE;
+       }
+       if (write_cmd(this, "RCPT TO:<%s>", to) != 250)
+       {
+               DBG1(DBG_LIB, "SMTP RCPT TO failed");
+               return FALSE;
+       }
+       if (write_cmd(this, "DATA") != 354)
+       {
+               DBG1(DBG_LIB, "SMTP DATA failed");
+               return FALSE;
+       }
+
+       fprintf(this->f, "From: %s\n", from);
+       fprintf(this->f, "To: %s\n", to);
+       fprintf(this->f, "Subject: %s\n", subject);
+       fprintf(this->f, "\n");
+       va_start(args, fmt);
+       vfprintf(this->f, fmt, args);
+       va_end(args);
+       fprintf(this->f, "\n.\n");
+       return read_response(this) == 250;
+}
+
+
+METHOD(fast_smtp_t, destroy, void,
+       private_fast_smtp_t *this)
+{
+       write_cmd(this, "QUIT");
+       fclose(this->f);
+       free(this);
+}
+
+/**
+ * See header
+ */
+fast_smtp_t *fast_smtp_create()
+{
+       private_fast_smtp_t *this;
+       struct sockaddr_in addr = {
+               .sin_family = AF_INET,
+               .sin_port = htons(25),
+               .sin_addr = {
+                       .s_addr = htonl(INADDR_LOOPBACK),
+               },
+       };
+       int s;
+
+       INIT(this,
+               .public = {
+                       .send_mail = _send_mail,
+                       .destroy = _destroy,
+               },
+       );
+
+       s = socket(AF_INET, SOCK_STREAM, 0);
+       if (s < 0)
+       {
+               DBG1(DBG_LIB, "opening SMTP socket failed: %s", strerror(errno));
+               free(this);
+               return NULL;
+       }
+       if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+       {
+               DBG1(DBG_LIB, "connecting to SMTP server failed: %s", strerror(errno));
+               close(s);
+               free(this);
+               return NULL;
+       }
+       this->f = fdopen(s, "a+");
+       if (!this->f)
+       {
+               DBG1(DBG_LIB, "opening stream to SMTP server failed: %s",
+                        strerror(errno));
+               close(s);
+               free(this);
+               return NULL;
+       }
+       if (read_response(this) != 220 ||
+               write_cmd(this, "EHLO localhost") != 250)
+       {
+               DBG1(DBG_LIB, "SMTP EHLO failed");
+               fclose(this->f);
+               free(this);
+               return NULL;
+       }
+       return &this->public;
+}
diff --git a/src/libfast/fast_smtp.h b/src/libfast/fast_smtp.h
new file mode 100644 (file)
index 0000000..962ba2c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup fast_smtp fast_smtp
+ * @{ @ingroup libfast
+ */
+
+#ifndef FAST_SMTP_H_
+#define FAST_SMTP_H_
+
+typedef struct fast_smtp_t fast_smtp_t;
+
+#include <library.h>
+
+/**
+ * Ultra-minimalistic SMTP client. Works at most with Exim on localhost.
+ */
+struct fast_smtp_t {
+
+       /**
+        * Send an e-mail message.
+        *
+        * @param from          sender address
+        * @param to            recipient address
+        * @param subject       mail subject
+        * @param fmt           mail body format string
+        * @param ...           arguments for body format string
+        */
+       bool (*send_mail)(fast_smtp_t *this, char *from, char *to,
+                                         char *subject, char *fmt, ...);
+
+       /**
+        * Destroy a fast_smtp_t.
+        */
+       void (*destroy)(fast_smtp_t *this);
+};
+
+/**
+ * Create a smtp instance.
+ */
+fast_smtp_t *fast_smtp_create();
+
+#endif /** FAST_SMTP_H_ @}*/
diff --git a/src/libfast/filter.h b/src/libfast/filter.h
deleted file mode 100644 (file)
index 305a8bb..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-/*
- * @defgroup filter filter
- * @{ @ingroup libfast
- */
-
-#ifndef FILTER_H_
-#define FILTER_H_
-
-#include "request.h"
-#include "context.h"
-#include "controller.h"
-
-typedef struct filter_t filter_t;
-
-/**
- * Constructor function for a filter
- *
- * @param context              session specific context
- * @param param                        user supplied param
- */
-typedef filter_t *(*filter_constructor_t)(context_t* context, void *param);
-
-/**
- * Filter interface, to be implemented by users filters.
- */
-struct filter_t {
-
-       /**
-        * Called before the controller handles the request.
-        *
-        * @param request               HTTP request
-        * @param p1                    first parameter
-        * @param p2                    second parameter
-        * @param p3                    third parameter
-        * @param p4                    forth parameter
-        * @param p5                    fifth parameter
-        * @return                              TRUE to continue request handling
-        */
-       bool (*run)(filter_t *this, request_t *request,
-                               char *p0, char *p1, char *p2, char *p3, char *p4, char *p5);
-
-       /**
-        * Destroy the filter instance.
-        */
-       void (*destroy) (filter_t *this);
-};
-
-#endif /* FILTER_H_ @} */
diff --git a/src/libfast/request.c b/src/libfast/request.c
deleted file mode 100644 (file)
index 5d03227..0000000
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-
-#include "request.h"
-
-#include <library.h>
-#include <utils/debug.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <ClearSilver/ClearSilver.h>
-
-#include <threading/thread.h>
-#include <threading/thread_value.h>
-
-typedef struct private_request_t private_request_t;
-
-/**
- * private data of the task manager
- */
-struct private_request_t {
-
-       /**
-        * public functions
-        */
-       request_t public;
-
-       /**
-        * FastCGI request object
-        */
-       FCGX_Request req;
-
-       /**
-        * length of the req.envp array
-        */
-       int req_env_len;
-
-       /**
-        * ClearSilver CGI Kit context
-        */
-       CGI *cgi;
-
-       /**
-        * ClearSilver HDF dataset for this request
-        */
-       HDF *hdf;
-
-       /**
-        * close the session?
-        */
-       bool closed;
-
-       /**
-        * reference count
-        */
-       refcount_t ref;
-};
-
-/**
- * ClearSilver cgiwrap is not threadsave, so we use a private
- * context for each thread.
- */
-static thread_value_t *thread_this;
-
-/**
- * control variable for pthread_once
- */
-pthread_once_t once = PTHREAD_ONCE_INIT;
-
-/**
- * fcgiwrap read callback
- */
-static int read_cb(void *null, char *buf, int size)
-{
-       private_request_t *this = (private_request_t*)thread_this->get(thread_this);
-
-       return FCGX_GetStr(buf, size, this->req.in);
-}
-
-/**
- * fcgiwrap writef callback
- */
-static int writef_cb(void *null, const char *format, va_list args)
-{
-       private_request_t *this = (private_request_t*)thread_this->get(thread_this);
-
-       FCGX_VFPrintF(this->req.out, format, args);
-       return 0;
-}
-/**
- * fcgiwrap write callback
- */
-static int write_cb(void *null, const char *buf, int size)
-{
-       private_request_t *this = (private_request_t*)thread_this->get(thread_this);
-
-       return FCGX_PutStr(buf, size, this->req.out);
-}
-
-/**
- * fcgiwrap getenv callback
- */
-static char *getenv_cb(void *null, const char *key)
-{
-       char *value;
-       private_request_t *this = (private_request_t*)thread_this->get(thread_this);
-
-       value = FCGX_GetParam(key, this->req.envp);
-       return strdupnull(value);
-}
-
-/**
- * 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;
-       private_request_t *this = (private_request_t*)thread_this->get(thread_this);
-       if (num < this->req_env_len)
-       {
-               char *eq;
-
-               eq = strchr(this->req.envp[num], '=');
-               if (eq)
-               {
-                       *key = strndup(this->req.envp[num], eq - this->req.envp[num]);
-                       *value = strdup(eq + 1);
-               }
-               if (*key == NULL || *value == NULL)
-               {
-                       free(*key);
-                       free(*value);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-METHOD(request_t, get_cookie, char*,
-       private_request_t *this, char *name)
-{
-       return hdf_get_valuef(this->hdf, "Cookie.%s", name);
-}
-
-METHOD(request_t, get_path, char*,
-       private_request_t *this)
-{
-       char * path = FCGX_GetParam("PATH_INFO", this->req.envp);
-       return path ? path : "";
-}
-
-METHOD(request_t, get_host, char*,
-       private_request_t *this)
-{
-       char *addr = FCGX_GetParam("REMOTE_ADDR", this->req.envp);
-       return addr ? addr : "";
-}
-
-METHOD(request_t, get_user_agent, char*,
-       private_request_t *this)
-{
-       char *agent = FCGX_GetParam("HTTP_USER_AGENT", this->req.envp);
-       return agent ? agent : "";
-}
-
-METHOD(request_t, get_query_data, char*,
-       private_request_t *this, char *name)
-{
-       return hdf_get_valuef(this->hdf, "Query.%s", name);
-}
-
-METHOD(request_t, get_env_var, char*,
-       private_request_t *this, char *name)
-{
-       return FCGX_GetParam(name, this->req.envp);
-}
-
-METHOD(request_t, read_data, int,
-       private_request_t *this, char *buf, int len)
-{
-       return FCGX_GetStr(buf, len, this->req.in);
-}
-
-METHOD(request_t, get_base, char*,
-       private_request_t *this)
-{
-       return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
-}
-
-METHOD(request_t, add_cookie, void,
-       private_request_t *this, char *name, char *value)
-{
-       thread_this->set(thread_this, this);
-       cgi_cookie_set(this->cgi, name, value, NULL, NULL, NULL, 0, 0);
-}
-
-METHOD(request_t, redirect, void,
-       private_request_t *this, char *fmt, ...)
-{
-       va_list args;
-
-       FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
-       FCGX_FPrintF(this->req.out, "Location: %s%s", get_base(this),
-                                *fmt == '/' ? "" : "/");
-       va_start(args, fmt);
-       FCGX_VFPrintF(this->req.out, fmt, args);
-       va_end(args);
-       FCGX_FPrintF(this->req.out, "\n\n");
-}
-
-METHOD(request_t, get_referer, char*,
-       private_request_t *this)
-{
-       return FCGX_GetParam("HTTP_REFERER", this->req.envp);
-}
-
-METHOD(request_t, to_referer, void,
-       private_request_t *this)
-{
-       char *referer;
-
-       referer = get_referer(this);
-       if (referer)
-       {
-               FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
-               FCGX_FPrintF(this->req.out, "Location: %s\n\n", referer);
-       }
-       else
-       {
-               redirect(this, "/");
-       }
-}
-
-METHOD(request_t, session_closed, bool,
-       private_request_t *this)
-{
-       return this->closed;
-}
-
-METHOD(request_t, close_session, void,
-       private_request_t *this)
-{
-       this->closed = TRUE;
-}
-
-METHOD(request_t, serve, void,
-       private_request_t *this, char *headers, chunk_t chunk)
-{
-       FCGX_FPrintF(this->req.out, "%s\n\n", headers);
-
-       FCGX_PutStr(chunk.ptr, chunk.len, this->req.out);
-}
-
-METHOD(request_t, sendfile, bool,
-       private_request_t *this, char *path, char *mime)
-{
-       struct stat sb;
-       chunk_t data;
-       void *addr;
-       int fd, written;
-       char buf[24];
-
-       fd = open(path, O_RDONLY);
-       if (fd == -1)
-       {
-               return FALSE;
-       }
-       if (fstat(fd, &sb) == -1)
-       {
-               close(fd);
-               return FALSE;
-       }
-       addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (addr == MAP_FAILED)
-       {
-               close(fd);
-               return FALSE;
-       }
-
-       /* FCGX does not like large integers, print to a buffer using libc */
-       snprintf(buf, sizeof(buf), "%lld", (int64_t)sb.st_size);
-       FCGX_FPrintF(this->req.out, "Content-Length: %s\n", buf);
-       if (mime)
-       {
-               FCGX_FPrintF(this->req.out, "Content-Type: %s\n", mime);
-       }
-       FCGX_FPrintF(this->req.out, "\n");
-
-       data = chunk_create(addr, sb.st_size);
-
-       while (data.len)
-       {
-               written = FCGX_PutStr(data.ptr, data.len, this->req.out);
-               if (written == -1)
-               {
-                       munmap(addr, sb.st_size);
-                       close(fd);
-                       return FALSE;
-               }
-               data = chunk_skip(data, written);
-       }
-
-       munmap(addr, sb.st_size);
-       close(fd);
-       return TRUE;
-}
-
-METHOD(request_t, render, void,
-       private_request_t *this, char *template)
-{
-       NEOERR* err;
-
-       thread_this->set(thread_this, this);
-       err = cgi_display(this->cgi, template);
-       if (err)
-       {
-               cgi_neo_error(this->cgi, err);
-               nerr_log_error(err);
-       }
-}
-
-METHOD(request_t, streamf, int,
-       private_request_t *this, char *format, ...)
-{
-       va_list args;
-       int written;
-
-       va_start(args, format);
-       written = FCGX_VFPrintF(this->req.out, format, args);
-       va_end(args);
-       if (written >= 0 &&
-               FCGX_FFlush(this->req.out) == -1)
-       {
-               return -1;
-       }
-       return written;
-}
-
-METHOD(request_t, set, void,
-       private_request_t *this, char *key, char *value)
-{
-       hdf_set_value(this->hdf, key, value);
-}
-
-METHOD(request_t, setf, void,
-       private_request_t *this, char *format, ...)
-{
-       va_list args;
-
-       va_start(args, format);
-       hdf_set_valuevf(this->hdf, format, args);
-       va_end(args);
-}
-
-METHOD(request_t, get_ref, request_t*,
-       private_request_t *this)
-{
-       ref_get(&this->ref);
-       return &this->public;
-}
-
-METHOD(request_t, destroy, void,
-       private_request_t *this)
-{
-       if (ref_put(&this->ref))
-       {
-               thread_this->set(thread_this, this);
-               cgi_destroy(&this->cgi);
-               FCGX_Finish_r(&this->req);
-               free(this);
-       }
-}
-
-/**
- * This initialization method is guaranteed to run only once
- * for all threads.
- */
-static void init(void)
-{
-       cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
-                                        getenv_cb, putenv_cb, iterenv_cb);
-       thread_this = thread_value_create(NULL);
-}
-
-/*
- * see header file
- */
-request_t *request_create(int fd, bool debug)
-{
-       NEOERR* err;
-       private_request_t *this;
-       bool failed = FALSE;
-
-       INIT(this,
-               .public = {
-                       .get_path = _get_path,
-                       .get_base = _get_base,
-                       .get_host = _get_host,
-                       .get_user_agent = _get_user_agent,
-                       .add_cookie = _add_cookie,
-                       .get_cookie = _get_cookie,
-                       .get_query_data = _get_query_data,
-                       .get_env_var = _get_env_var,
-                       .read_data = _read_data,
-                       .session_closed = _session_closed,
-                       .close_session = _close_session,
-                       .redirect = _redirect,
-                       .get_referer = _get_referer,
-                       .to_referer = _to_referer,
-                       .render = _render,
-                       .streamf = _streamf,
-                       .serve = _serve,
-                       .sendfile = _sendfile,
-                       .set = _set,
-                       .setf = _setf,
-                       .get_ref = _get_ref,
-                       .destroy = _destroy,
-               },
-               .ref = 1,
-       );
-
-       thread_cleanup_push(free, this);
-       if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
-               FCGX_Accept_r(&this->req) != 0)
-       {
-               failed = TRUE;
-       }
-       thread_cleanup_pop(failed);
-       if (failed)
-       {
-               return NULL;
-       }
-
-       pthread_once(&once, init);
-       thread_this->set(thread_this, this);
-
-       while (this->req.envp[this->req_env_len] != NULL)
-       {
-               this->req_env_len++;
-       }
-
-       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");
-               }
-
-               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);
-       FCGX_Finish_r(&this->req);
-       free(this);
-       return NULL;
-}
-
diff --git a/src/libfast/request.h b/src/libfast/request.h
deleted file mode 100644 (file)
index 63a465b..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup request request
- * @{ @ingroup libfast
- */
-
-#ifndef REQUEST_H_
-#define REQUEST_H_
-
-#include <fcgiapp.h>
-#include <library.h>
-
-typedef struct request_t request_t;
-
-/**
- * A HTTP request, encapsulates FCGX_Request.
- *
- * The response is also handled through the request object.
- */
-struct request_t {
-
-       /**
-        * 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);
-
-       /**
-        * Get a cookie the client sent in the request.
-        *
-        * @param name          name of the cookie
-        * @return                      cookie value, NULL if no such cookie found
-        */
-       char* (*get_cookie)(request_t *this, char *name);
-
-       /**
-        * Get the request path relative to the application.
-        *
-        * @return                      path
-        */
-       char* (*get_path)(request_t *this);
-
-       /**
-        * Get the base path of the application.
-        *
-        * @return                      base path
-        */
-       char* (*get_base)(request_t *this);
-
-       /**
-        * Get the remote host address of this request.
-        *
-        * @return                      host address as string
-        */
-       char* (*get_host)(request_t *this);
-
-       /**
-        * Get the user agent string.
-        *
-        * @return                      user agent string
-        */
-       char* (*get_user_agent)(request_t *this);
-
-       /**
-        * 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_query_data)(request_t *this, char *name);
-
-       /**
-        * Get an arbitrary environment variable.
-        *
-        * @param name          name of the environment variable
-        * @return                      value, NULL if not found
-        */
-       char* (*get_env_var)(request_t *this, char *name);
-
-       /**
-        * Read raw POST/PUT data from HTTP request.
-        *
-        * @param buf           buffer to read data into
-        * @param len           size of the supplied buffer
-        * @return                      number of bytes read, < 0 on error
-        */
-       int (*read_data)(request_t *this, char *buf, int len);
-
-       /**
-        * Close the session and it's context after handling.
-        */
-       void (*close_session)(request_t *this);
-
-       /**
-        * Has the session been closed by close_session()?
-        *
-        * @return                      TRUE if session has been closed
-        */
-       bool (*session_closed)(request_t *this);
-
-       /**
-        * Redirect the client to another location.
-        *
-        * @param fmt           location format string
-        * @param ...           variable argument for fmt
-        */
-       void (*redirect)(request_t *this, char *fmt, ...);
-
-       /**
-        * Get the HTTP referer.
-        *
-        * @return                      HTTP referer
-        */
-       char* (*get_referer)(request_t *this);
-
-       /**
-        * Redirect back to the referer.
-        */
-       void (*to_referer)(request_t *this);
-
-       /**
-        * 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);
-
-       /**
-        * 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, ...);
-
-       /**
-        * 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
-        */
-       void (*render)(request_t *this, char *template);
-
-       /**
-        * Stream a format string to the client.
-        *
-        * Stream is not closed and may be called multiple times to allow
-        * server-push functionality.
-        *
-        * @param format        printf like format string
-        * @param ...           argmuent list to format string
-        * @return                      number of streamed bytes, < 0 if stream closed
-        */
-       int (*streamf)(request_t *this, char *format, ...);
-
-       /**
-        * Serve a request with headers and a body.
-        *
-        * @param headers       HTTP headers, \n separated
-        * @param chunk         body to write to output
-        */
-       void (*serve)(request_t *this, char *headers, chunk_t chunk);
-
-       /**
-        * Send a file from the file system.
-        *
-        * @param path          path to file to serve
-        * @param mime          mime type of file to send, or NULL
-        * @return                      TRUE if file served successfully
-        */
-       bool (*sendfile)(request_t *this, char *path, char *mime);
-
-       /**
-        * Increase the reference count to the stream.
-        *
-        * @return                      this with increased refcount
-        */
-       request_t* (*get_ref)(request_t *this);
-
-       /**
-        * Destroy the request_t.
-        */
-       void (*destroy) (request_t *this);
-};
-
-/**
- * Create a request from the fastcgi struct.
- *
- * @param fd                   file descripter opened with FCGX_OpenSocket
- * @param debug                        no stripping, no compression, timing information
- */
-request_t *request_create(int fd, bool debug);
-
-#endif /** REQUEST_H_ @}*/
diff --git a/src/libfast/session.c b/src/libfast/session.c
deleted file mode 100644 (file)
index 87a157b..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.
- */
-
-#define _GNU_SOURCE
-
-#include "session.h"
-
-#include <string.h>
-#include <fcgiapp.h>
-#include <stdio.h>
-
-#include <collections/linked_list.h>
-
-#define COOKIE_LEN 16
-
-typedef struct private_session_t private_session_t;
-
-/**
- * private data of the task manager
- */
-struct private_session_t {
-
-       /**
-        * public functions
-        */
-       session_t public;
-
-       /**
-        * session ID
-        */
-       char sid[COOKIE_LEN * 2 + 1];
-
-       /**
-        * have we sent the session cookie?
-        */
-       bool cookie_sent;
-
-       /**
-        * list of controller instances controller_t
-        */
-       linked_list_t *controllers;
-
-       /**
-        * list of filter instances filter_t
-        */
-       linked_list_t *filters;
-
-       /**
-        * user defined session context
-        */
-       context_t *context;
-};
-
-METHOD(session_t, add_controller, void,
-       private_session_t *this, controller_t *controller)
-{
-       this->controllers->insert_last(this->controllers, controller);
-}
-
-METHOD(session_t, add_filter, void,
-       private_session_t *this, filter_t *filter)
-{
-       this->filters->insert_last(this->filters, filter);
-}
-
-/**
- * Create a session ID and a cookie
- */
-static bool create_sid(private_session_t *this)
-{
-       char buf[COOKIE_LEN];
-       rng_t *rng;
-
-       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
-       {
-               return FALSE;
-       }
-       if (!rng->get_bytes(rng, sizeof(buf), buf))
-       {
-               rng->destroy(rng);
-               return FALSE;
-       }
-       rng->destroy(rng);
-       chunk_to_hex(chunk_create(buf, sizeof(buf)), this->sid, FALSE);
-       return TRUE;
-}
-
-/**
- * run all registered filters
- */
-static bool run_filter(private_session_t *this, request_t *request, char *p0,
-                                          char *p1, char *p2, char *p3, char *p4, char *p5)
-{
-       enumerator_t *enumerator;
-       filter_t *filter;
-
-       enumerator = this->filters->create_enumerator(this->filters);
-       while (enumerator->enumerate(enumerator, &filter))
-       {
-               if (!filter->run(filter, request, p0, p1, p2, p3, p4, p5))
-               {
-                       enumerator->destroy(enumerator);
-                       return FALSE;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return TRUE;
-}
-
-METHOD(session_t, process, void,
-       private_session_t *this, request_t *request)
-{
-       char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
-       enumerator_t *enumerator;
-       bool handled = FALSE;
-       controller_t *current;
-       int i = 0;
-
-       if (!this->cookie_sent)
-       {
-               request->add_cookie(request, "SID", this->sid);
-               this->cookie_sent = TRUE;
-       }
-
-       start = request->get_path(request);
-       if (start)
-       {
-               if (*start == '/')
-               {
-                       start++;
-               }
-               while ((pos = strchr(start, '/')) != NULL && i < 5)
-               {
-                       param[i++] = strndupa(start, pos - start);
-                       start = pos + 1;
-               }
-               param[i] = strdupa(start);
-
-               if (run_filter(this, request, param[0], param[1], param[2], param[3],
-                                               param[4], param[5]))
-               {
-                       enumerator = this->controllers->create_enumerator(this->controllers);
-                       while (enumerator->enumerate(enumerator, &current))
-                       {
-                               if (streq(current->get_name(current), param[0]))
-                               {
-                                       current->handle(current, request, param[1], param[2],
-                                                                       param[3], param[4], param[5]);
-                                       handled = TRUE;
-                                       break;
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-               }
-               else
-               {
-                       handled = TRUE;
-               }
-       }
-       if (!handled)
-       {
-               if (this->controllers->get_first(this->controllers,
-                                                                                (void**)&current) == SUCCESS)
-               {
-                       request->streamf(request,
-                               "Status: 301 Moved permanently\nLocation: %s/%s\n\n",
-                               request->get_base(request), current->get_name(current));
-               }
-       }
-}
-
-METHOD(session_t, get_sid, char*,
-       private_session_t *this)
-{
-       return this->sid;
-}
-
-METHOD(session_t, destroy, void,
-       private_session_t *this)
-{
-       this->controllers->destroy_offset(this->controllers, offsetof(controller_t, destroy));
-       this->filters->destroy_offset(this->filters, offsetof(filter_t, destroy));
-       DESTROY_IF(this->context);
-       free(this);
-}
-
-/*
- * see header file
- */
-session_t *session_create(context_t *context)
-{
-       private_session_t *this;
-
-       INIT(this,
-               .public = {
-                       .add_controller = _add_controller,
-                       .add_filter = _add_filter,
-                       .process = _process,
-                       .get_sid = _get_sid,
-                       .destroy = _destroy,
-               },
-               .controllers = linked_list_create(),
-               .filters = linked_list_create(),
-               .context = context,
-       );
-       if (!create_sid(this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
diff --git a/src/libfast/session.h b/src/libfast/session.h
deleted file mode 100644 (file)
index acbab89..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup session session
- * @{ @ingroup libfast
- */
-
-#ifndef SESSION_H_
-#define SESSION_H_
-
-#include "request.h"
-#include "controller.h"
-#include "filter.h"
-
-typedef struct session_t session_t;
-
-/**
- * Session handling class, instanciated for each user session.
- */
-struct session_t {
-
-       /**
-        * Get the session ID of the session.
-        *
-        * @return                              session ID
-        */
-       char* (*get_sid)(session_t *this);
-
-       /**
-        * Add a controller instance to the session.
-        *
-        * @param controller    controller to add
-        */
-       void (*add_controller)(session_t *this, controller_t *controller);
-
-       /**
-        * Add a filter instance to the session.
-        *
-        * @param filter                filter to add
-        */
-       void (*add_filter)(session_t *this, filter_t *filter);
-
-       /**
-        * Process a request in this session.
-        *
-        * @param request               request to process
-        */
-       void (*process)(session_t *this, request_t *request);
-
-       /**
-        * Destroy the session_t.
-        */
-       void (*destroy) (session_t *this);
-};
-
-/**
- * Create a session new session.
- *
- * @param context              user defined session context instance
- * @return                             client session, NULL on error
- */
-session_t *session_create(context_t *context);
-
-#endif /** SESSION_H_ @}*/
diff --git a/src/libfast/smtp.c b/src/libfast/smtp.c
deleted file mode 100644 (file)
index a6ca67d..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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 "smtp.h"
-
-#include <unistd.h>
-#include <errno.h>
-
-#include <utils/debug.h>
-
-typedef struct private_smtp_t private_smtp_t;
-
-/**
- * Private data of an smtp_t object.
- */
-struct private_smtp_t {
-
-       /**
-        * Public smtp_t interface.
-        */
-       smtp_t public;
-
-       /**
-        * file stream to SMTP server
-        */
-       FILE *f;
-};
-
-/**
- * Read the response code from an SMTP server
- */
-static int read_response(private_smtp_t *this)
-{
-       char buf[256], *end;
-       int res = 0;
-
-       while (TRUE)
-       {
-               if (!fgets(buf, sizeof(buf), this->f))
-               {
-                       return 0;
-               }
-               res = strtol(buf, &end, 10);
-               switch (*end)
-               {
-                       case '-':
-                               continue;
-                       case ' ':
-                       case '\0':
-                       case '\n':
-                               break;
-                       default:
-                               return 0;
-               }
-               break;
-       }
-       return res;
-}
-
-/**
- * write a SMTP command to the server, read response code
- */
-static int write_cmd(private_smtp_t *this, char *fmt, ...)
-{
-       char buf[256];
-       va_list args;
-
-       va_start(args, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-
-       if (fprintf(this->f, "%s\n", buf) < 1)
-       {
-               DBG1(DBG_LIB, "sending SMTP command failed");
-               return 0;
-       }
-       return read_response(this);
-}
-
-METHOD(smtp_t, send_mail, bool,
-       private_smtp_t *this, char *from, char *to, char *subject, char *fmt, ...)
-{
-       va_list args;
-
-       if (write_cmd(this, "MAIL FROM:<%s>", from) != 250)
-       {
-               DBG1(DBG_LIB, "SMTP MAIL FROM failed");
-               return FALSE;
-       }
-       if (write_cmd(this, "RCPT TO:<%s>", to) != 250)
-       {
-               DBG1(DBG_LIB, "SMTP RCPT TO failed");
-               return FALSE;
-       }
-       if (write_cmd(this, "DATA") != 354)
-       {
-               DBG1(DBG_LIB, "SMTP DATA failed");
-               return FALSE;
-       }
-
-       fprintf(this->f, "From: %s\n", from);
-       fprintf(this->f, "To: %s\n", to);
-       fprintf(this->f, "Subject: %s\n", subject);
-       fprintf(this->f, "\n");
-       va_start(args, fmt);
-       vfprintf(this->f, fmt, args);
-       va_end(args);
-       fprintf(this->f, "\n.\n");
-       return read_response(this) == 250;
-}
-
-
-METHOD(smtp_t, destroy, void,
-       private_smtp_t *this)
-{
-       write_cmd(this, "QUIT");
-       fclose(this->f);
-       free(this);
-}
-
-/**
- * See header
- */
-smtp_t *smtp_create()
-{
-       private_smtp_t *this;
-       struct sockaddr_in addr = {
-               .sin_family = AF_INET,
-               .sin_port = htons(25),
-               .sin_addr = {
-                       .s_addr = htonl(INADDR_LOOPBACK),
-               },
-       };
-       int s;
-
-       INIT(this,
-               .public = {
-                       .send_mail = _send_mail,
-                       .destroy = _destroy,
-               },
-       );
-
-       s = socket(AF_INET, SOCK_STREAM, 0);
-       if (s < 0)
-       {
-               DBG1(DBG_LIB, "opening SMTP socket failed: %s", strerror(errno));
-               free(this);
-               return NULL;
-       }
-       if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0)
-       {
-               DBG1(DBG_LIB, "connecting to SMTP server failed: %s", strerror(errno));
-               close(s);
-               free(this);
-               return NULL;
-       }
-       this->f = fdopen(s, "a+");
-       if (!this->f)
-       {
-               DBG1(DBG_LIB, "opening stream to SMTP server failed: %s",
-                        strerror(errno));
-               close(s);
-               free(this);
-               return NULL;
-       }
-       if (read_response(this) != 220 ||
-               write_cmd(this, "EHLO localhost") != 250)
-       {
-               DBG1(DBG_LIB, "SMTP EHLO failed");
-               fclose(this->f);
-               free(this);
-               return NULL;
-       }
-       return &this->public;
-}
-
diff --git a/src/libfast/smtp.h b/src/libfast/smtp.h
deleted file mode 100644 (file)
index 9589ea2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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.
- */
-
-/**
- * @defgroup smtp smtp
- * @{ @ingroup libfast
- */
-
-#ifndef SMTP_H_
-#define SMTP_H_
-
-typedef struct smtp_t smtp_t;
-
-#include <library.h>
-
-/**
- * Ultra-minimalistic SMTP client. Works at most with Exim on localhost.
- */
-struct smtp_t {
-
-       /**
-        * Send an e-mail message.
-        *
-        * @param from          sender address
-        * @param to            recipient address
-        * @param subject       mail subject
-        * @param fmt           mail body format string
-        * @param ...           arguments for body format string
-        */
-       bool (*send_mail)(smtp_t *this, char *from, char *to,
-                                         char *subject, char *fmt, ...);
-
-       /**
-        * Destroy a smtp_t.
-        */
-       void (*destroy)(smtp_t *this);
-};
-
-/**
- * Create a smtp instance.
- */
-smtp_t *smtp_create();
-
-#endif /** SMTP_H_ @}*/
index c9a9b54..5f2de51 100644 (file)
@@ -37,14 +37,14 @@ struct private_auth_controller_t {
        manager_t *manager;
 };
 
-static void login(private_auth_controller_t *this, request_t *request)
+static void login(private_auth_controller_t *this, fast_request_t *request)
 {
        request->set(request, "action", "check");
        request->set(request, "title", "Login");
        request->render(request, "templates/auth/login.cs");
 }
 
-static void check(private_auth_controller_t *this, request_t *request)
+static void check(private_auth_controller_t *this, fast_request_t *request)
 {
        char *username, *password;
 
@@ -61,20 +61,20 @@ static void check(private_auth_controller_t *this, request_t *request)
        }
 }
 
-static void logout(private_auth_controller_t *this, request_t *request)
+static void logout(private_auth_controller_t *this, fast_request_t *request)
 {
        this->manager->logout(this->manager);
        request->redirect(request, "auth/login");
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_auth_controller_t *this)
 {
        return "auth";
 }
 
-METHOD(controller_t, handle, void,
-       private_auth_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_auth_controller_t *this, fast_request_t *request, char *action,
        char *p2, char *p3, char *p4, char *p5)
 {
        if (action)
@@ -95,7 +95,7 @@ METHOD(controller_t, handle, void,
        request->redirect(request, "auth/login");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_auth_controller_t *this)
 {
        free(this);
@@ -104,7 +104,7 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *auth_controller_create(context_t *context, void *param)
+fast_controller_t *auth_controller_create(fast_context_t *context, void *param)
 {
        private_auth_controller_t *this;
 
@@ -121,4 +121,3 @@ controller_t *auth_controller_create(context_t *context, void *param)
 
        return &this->public.controller;
 }
-
index 8489d9d..0729227 100644 (file)
@@ -21,8 +21,7 @@
 #ifndef AUTH_CONTROLLER_H_
 #define AUTH_CONTROLLER_H_
 
-
-#include <controller.h>
+#include <fast_controller.h>
 
 typedef struct auth_controller_t auth_controller_t;
 
@@ -34,12 +33,12 @@ struct auth_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a auth_controller controller instance.
  */
-controller_t *auth_controller_create(context_t *context, void *param);
+fast_controller_t *auth_controller_create(fast_context_t *context, void *param);
 
 #endif /** AUTH_CONTROLLER_H_ @}*/
index 154ab61..bc93c54 100644 (file)
@@ -44,7 +44,7 @@ struct private_config_controller_t {
  * read XML of a peerconfig element and fill template
  */
 static void process_peerconfig(private_config_controller_t *this,
-                                                          enumerator_t *e, request_t *r)
+                                                          enumerator_t *e, fast_request_t *r)
 {
        xml_t *xml;
        enumerator_t *e1, *e2, *e3;
@@ -115,7 +115,7 @@ static void process_peerconfig(private_config_controller_t *this,
        }
 }
 
-static void list(private_config_controller_t *this, request_t *r)
+static void list(private_config_controller_t *this, fast_request_t *r)
 {
        gateway_t *gateway;
        xml_t *xml;
@@ -149,14 +149,14 @@ static void list(private_config_controller_t *this, request_t *r)
        }
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_config_controller_t *this)
 {
        return "config";
 }
 
-METHOD(controller_t, handle, void,
-       private_config_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_config_controller_t *this, fast_request_t *request, char *action,
        char *p2, char *p3, char *p4, char *p5)
 {
        if (!this->manager->logged_in(this->manager))
@@ -177,7 +177,7 @@ METHOD(controller_t, handle, void,
        return request->redirect(request, "config/list");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_config_controller_t *this)
 {
        free(this);
@@ -186,7 +186,8 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *config_controller_create(context_t *context, void *param)
+fast_controller_t *config_controller_create(fast_context_t *context,
+                                                                                       void *param)
 {
        private_config_controller_t *this;
 
@@ -203,4 +204,3 @@ controller_t *config_controller_create(context_t *context, void *param)
 
        return &this->public.controller;
 }
-
index a84678c..504ec8c 100644 (file)
@@ -21,8 +21,7 @@
 #ifndef CONFIG_CONTROLLER_H_
 #define CONFIG_CONTROLLER_H_
 
-
-#include <controller.h>
+#include <fast_controller.h>
 
 typedef struct config_controller_t config_controller_t;
 
@@ -34,12 +33,13 @@ struct config_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a config_controller controller instance.
  */
-controller_t *config_controller_create(context_t *context, void *param);
+fast_controller_t *config_controller_create(fast_context_t *context,
+                                                                                       void *param);
 
 #endif /** CONFIG_CONTROLLER_H_ @}*/
index 68238d0..f275986 100644 (file)
@@ -43,7 +43,7 @@ struct private_control_controller_t {
 /**
  * handle the result of a control operation
  */
-static void handle_result(private_control_controller_t *this, request_t *r,
+static void handle_result(private_control_controller_t *this, fast_request_t *r,
                                                  enumerator_t *e)
 {
        enumerator_t *e1;
@@ -93,7 +93,7 @@ static void handle_result(private_control_controller_t *this, request_t *r,
 /**
  * initiate an IKE or CHILD SA
  */
-static void initiate(private_control_controller_t *this, request_t *r,
+static void initiate(private_control_controller_t *this, fast_request_t *r,
                                         bool ike, char *config)
 {
        gateway_t *gateway;
@@ -108,7 +108,7 @@ static void initiate(private_control_controller_t *this, request_t *r,
 /**
  * terminate an IKE or CHILD SA
  */
-static void terminate(private_control_controller_t *this, request_t *r,
+static void terminate(private_control_controller_t *this, fast_request_t *r,
                                          bool ike, u_int32_t id)
 {
        gateway_t *gateway;
@@ -120,14 +120,14 @@ static void terminate(private_control_controller_t *this, request_t *r,
        handle_result(this, r, e);
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_control_controller_t *this)
 {
        return "control";
 }
 
-METHOD(controller_t, handle, void,
-       private_control_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_control_controller_t *this, fast_request_t *request, char *action,
        char *str, char *p3, char *p4, char *p5)
 {
        if (!this->manager->logged_in(this->manager))
@@ -174,7 +174,7 @@ METHOD(controller_t, handle, void,
        return request->redirect(request, "ikesa/list");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_control_controller_t *this)
 {
        free(this);
@@ -183,7 +183,8 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *control_controller_create(context_t *context, void *param)
+fast_controller_t *control_controller_create(fast_context_t *context,
+                                                                                        void *param)
 {
        private_control_controller_t *this;
 
@@ -200,4 +201,3 @@ controller_t *control_controller_create(context_t *context, void *param)
 
        return &this->public.controller;
 }
-
index 22e3a70..0342f8c 100644 (file)
@@ -21,8 +21,7 @@
 #ifndef CONTROL_CONTROLLER_H_
 #define CONTROL_CONTROLLER_H_
 
-
-#include <controller.h>
+#include <fast_controller.h>
 
 typedef struct control_controller_t control_controller_t;
 
@@ -34,12 +33,13 @@ struct control_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a control_controller controller instance.
  */
-controller_t *control_controller_create(context_t *context, void *param);
+fast_controller_t *control_controller_create(fast_context_t *context,
+                                                                                        void *param);
 
 #endif /** CONTROL_CONTROLLER_H_ @}*/
index 39d3445..6c02579 100644 (file)
@@ -39,7 +39,7 @@ struct private_gateway_controller_t {
 
 };
 
-static void list(private_gateway_controller_t *this, request_t *request)
+static void list(private_gateway_controller_t *this, fast_request_t *request)
 {
        enumerator_t *enumerator;
        char *name, *address;
@@ -66,7 +66,7 @@ static void list(private_gateway_controller_t *this, request_t *request)
        request->render(request, "templates/gateway/list.cs");
 }
 
-static void _select(private_gateway_controller_t *this, request_t *request)
+static void _select(private_gateway_controller_t *this, fast_request_t *request)
 {
        char *id;
 
@@ -82,14 +82,14 @@ static void _select(private_gateway_controller_t *this, request_t *request)
        request->redirect(request, "gateway/list");
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_gateway_controller_t *this)
 {
        return "gateway";
 }
 
-METHOD(controller_t, handle, void,
-       private_gateway_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_gateway_controller_t *this, fast_request_t *request, char *action,
        char *p2, char *p3, char *p4, char *p5)
 {
        if (!this->manager->logged_in(this->manager))
@@ -110,7 +110,7 @@ METHOD(controller_t, handle, void,
        request->redirect(request, "gateway/list");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_gateway_controller_t *this)
 {
        free(this);
@@ -119,7 +119,8 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *gateway_controller_create(context_t *context, void *param)
+fast_controller_t *gateway_controller_create(fast_context_t *context,
+                                                                                        void *param)
 {
        private_gateway_controller_t *this;
 
@@ -136,4 +137,3 @@ controller_t *gateway_controller_create(context_t *context, void *param)
 
        return &this->public.controller;
 }
-
index a099929..170bc1b 100644 (file)
@@ -21,8 +21,7 @@
 #ifndef GATEWAY_CONTROLLER_H_
 #define GATEWAY_CONTROLLER_H_
 
-
-#include <controller.h>
+#include <fast_controller.h>
 
 typedef struct gateway_controller_t gateway_controller_t;
 
@@ -34,12 +33,13 @@ struct gateway_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a gateway_controller controller instance.
  */
-controller_t *gateway_controller_create(context_t *context, void *param);
+fast_controller_t *gateway_controller_create(fast_context_t *context,
+                                                                                        void *param);
 
 #endif /** GATEWAY_CONTROLLER_H_ @}*/
index 716d51a..df0e5f4 100644 (file)
@@ -44,7 +44,7 @@ struct private_ikesa_controller_t {
  * read XML of a childsa element and fill template
  */
 static void process_childsa(private_ikesa_controller_t *this, char *id,
-                                                       enumerator_t *e, request_t *r)
+                                                       enumerator_t *e, fast_request_t *r)
 {
        xml_t *xml;
        enumerator_t *e1, *e2;
@@ -96,7 +96,7 @@ static void process_childsa(private_ikesa_controller_t *this, char *id,
  * read XML of a ikesa element and fill template
  */
 static void process_ikesa(private_ikesa_controller_t *this,
-                                                 enumerator_t *e, request_t *r)
+                                                 enumerator_t *e, fast_request_t *r)
 {
        xml_t *xml;
        enumerator_t *e1, *e2;
@@ -139,7 +139,7 @@ static void process_ikesa(private_ikesa_controller_t *this,
        }
 }
 
-static void list(private_ikesa_controller_t *this, request_t *r)
+static void list(private_ikesa_controller_t *this, fast_request_t *r)
 {
        gateway_t *gateway;
        xml_t *xml;
@@ -173,14 +173,14 @@ static void list(private_ikesa_controller_t *this, request_t *r)
        }
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_ikesa_controller_t *this)
 {
        return "ikesa";
 }
 
-METHOD(controller_t, handle, void,
-       private_ikesa_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_ikesa_controller_t *this, fast_request_t *request, char *action,
        char *p2, char *p3, char *p4, char *p5)
 {
        if (!this->manager->logged_in(this->manager))
@@ -201,7 +201,7 @@ METHOD(controller_t, handle, void,
        return request->redirect(request, "ikesa/list");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_ikesa_controller_t *this)
 {
        free(this);
@@ -210,7 +210,7 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *ikesa_controller_create(context_t *context, void *param)
+fast_controller_t *ikesa_controller_create(fast_context_t *context, void *param)
 {
        private_ikesa_controller_t *this;
 
@@ -227,4 +227,3 @@ controller_t *ikesa_controller_create(context_t *context, void *param)
 
        return &this->public.controller;
 }
-
index 72f8242..5920475 100644 (file)
@@ -21,8 +21,7 @@
 #ifndef IKESA_CONTROLLER_H_
 #define IKESA_CONTROLLER_H_
 
-
-#include <controller.h>
+#include <fast_controller.h>
 
 typedef struct ikesa_controller_t ikesa_controller_t;
 
@@ -34,12 +33,12 @@ struct ikesa_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a ikesa_controller controller instance.
  */
-controller_t *ikesa_controller_create(context_t *context, void *param);
+fast_controller_t *ikesa_controller_create(fast_context_t *context, void *param);
 
 #endif /** IKESA_CONTROLLER_H_ @}*/
index 66a4384..5c845b1 100644 (file)
@@ -13,7 +13,7 @@
  * for more details.
  */
 
-#include <dispatcher.h>
+#include <fast_dispatcher.h>
 #include <utils/debug.h>
 #include <stdio.h>
 
@@ -27,7 +27,7 @@
 
 int main (int arc, char *argv[])
 {
-       dispatcher_t *dispatcher;
+       fast_dispatcher_t *dispatcher;
        storage_t *storage;
        char *socket;
        char *database;
@@ -50,7 +50,7 @@ int main (int arc, char *argv[])
        {
                DBG1(DBG_LIB, "database URI undefined, set manager.database "
                         "in strongswan.conf");
-               return 1;
+               //return 1;
        }
 
        storage = storage_create(database);
@@ -59,8 +59,8 @@ int main (int arc, char *argv[])
                return 1;
        }
 
-       dispatcher = dispatcher_create(socket, debug, timeout,
-                                               (context_constructor_t)manager_create, storage);
+       dispatcher = fast_dispatcher_create(socket, debug, timeout,
+                                               (fast_context_constructor_t)manager_create, storage);
        dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
        dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
        dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
@@ -78,4 +78,3 @@ int main (int arc, char *argv[])
 
        return 0;
 }
-
index 207800b..22a4191 100644 (file)
@@ -118,7 +118,7 @@ METHOD(manager_t, logout, void,
        this->user = 0;
 }
 
-METHOD(context_t, destroy, void,
+METHOD(fast_context_t, destroy, void,
        private_manager_t *this)
 {
        if (this->gateway) this->gateway->destroy(this->gateway);
@@ -148,4 +148,3 @@ manager_t *manager_create(storage_t *storage)
 
        return &this->public;
 }
-
index a72801f..e0ed7fc 100644 (file)
@@ -29,7 +29,7 @@
 #include "storage.h"
 #include "gateway.h"
 
-#include <context.h>
+#include <fast_context.h>
 
 typedef struct manager_t manager_t;
 
@@ -41,7 +41,7 @@ struct manager_t {
        /**
         * implements context_t interface
         */
-       context_t context;
+       fast_context_t context;
 
        /**
         * Create an enumerator over all configured gateways.
index 7b0b9e6..4943647 100644 (file)
@@ -52,7 +52,7 @@ struct private_peer_controller_t {
 /**
  * list the configured peer configs
  */
-static void list(private_peer_controller_t *this, request_t *request)
+static void list(private_peer_controller_t *this, fast_request_t *request)
 {
        enumerator_t *query;
 
@@ -83,7 +83,7 @@ static void list(private_peer_controller_t *this, request_t *request)
 /**
  * verify a peer alias
  */
-static bool verify_alias(private_peer_controller_t *this, request_t *request,
+static bool verify_alias(private_peer_controller_t *this, fast_request_t *request,
                                                 char *alias)
 {
        if (!alias || *alias == '\0')
@@ -117,7 +117,7 @@ static bool verify_alias(private_peer_controller_t *this, request_t *request,
  * parse and verify a public key
  */
 static bool parse_public_key(private_peer_controller_t *this,
-                                                        request_t *request, char *public_key,
+                                                        fast_request_t *request, char *public_key,
                                                         chunk_t *encoding, chunk_t *keyid)
 {
        public_key_t *public;
@@ -153,7 +153,7 @@ static bool parse_public_key(private_peer_controller_t *this,
 /**
  * register a new peer
  */
-static void add(private_peer_controller_t *this, request_t *request)
+static void add(private_peer_controller_t *this, fast_request_t *request)
 {
        char *alias = "", *public_key = "";
 
@@ -231,7 +231,7 @@ char* pem_encode(chunk_t der)
 /**
  * edit a peer
  */
-static void edit(private_peer_controller_t *this, request_t *request, int id)
+static void edit(private_peer_controller_t *this, fast_request_t *request, int id)
 {
        char *alias = "", *public_key = "", *pem;
        chunk_t encoding, keyid;
@@ -305,21 +305,21 @@ static void edit(private_peer_controller_t *this, request_t *request, int id)
 /**
  * delete a peer from the database
  */
-static void delete(private_peer_controller_t *this, request_t *request, int id)
+static void delete(private_peer_controller_t *this, fast_request_t *request, int id)
 {
        this->db->execute(this->db, NULL,
                                          "DELETE FROM peer WHERE id = ? AND user = ?",
                                          DB_INT, id, DB_UINT, this->user->get_user(this->user));
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_peer_controller_t *this)
 {
        return "peer";
 }
 
-METHOD(controller_t, handle, void,
-       private_peer_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_peer_controller_t *this, fast_request_t *request, char *action,
        char *idstr, char *p3, char *p4, char *p5)
 {
        if (action)
@@ -350,7 +350,7 @@ METHOD(controller_t, handle, void,
        request->redirect(request, "peer/list");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_peer_controller_t *this)
 {
        free(this);
@@ -359,7 +359,7 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *peer_controller_create(user_t *user, database_t *db)
+fast_controller_t *peer_controller_create(user_t *user, database_t *db)
 {
        private_peer_controller_t *this;
 
@@ -377,4 +377,3 @@ controller_t *peer_controller_create(user_t *user, database_t *db)
 
        return &this->public.controller;
 }
-
index b5a5e0b..1282156 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <user.h>
 
-#include <controller.h>
+#include <fast_controller.h>
 #include <database/database.h>
 
 typedef struct peer_controller_t peer_controller_t;
@@ -37,12 +37,12 @@ struct peer_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a peer_controller controller instance.
  */
-controller_t *peer_controller_create(user_t *user, database_t *db);
+fast_controller_t *peer_controller_create(user_t *user, database_t *db);
 
 #endif /** PEER_CONTROLLER_H_ @}*/
index 35c9d90..36d04e1 100644 (file)
@@ -76,7 +76,7 @@ static chunk_t hash_password(char *login, char *password)
 /**
  * Login a user.
  */
-static void login(private_user_controller_t *this, request_t *request)
+static void login(private_user_controller_t *this, fast_request_t *request)
 {
        if (request->get_query_data(request, "submit"))
        {
@@ -115,7 +115,7 @@ static void login(private_user_controller_t *this, request_t *request)
 /**
  * Logout a user.
  */
-static void logout(private_user_controller_t *this, request_t *request)
+static void logout(private_user_controller_t *this, fast_request_t *request)
 {
        request->redirect(request, "user/login");
        request->close_session(request);
@@ -124,8 +124,8 @@ static void logout(private_user_controller_t *this, request_t *request)
 /**
  * verify a user entered username for validity
  */
-static bool verify_login(private_user_controller_t *this, request_t *request,
-                                                char *login)
+static bool verify_login(private_user_controller_t *this,
+                                                fast_request_t *request, char *login)
 {
        if (!login || *login == '\0')
        {
@@ -156,7 +156,8 @@ static bool verify_login(private_user_controller_t *this, request_t *request,
 /**
  * verify a user entered password for validity
  */
-static bool verify_password(private_user_controller_t *this, request_t *request,
+static bool verify_password(private_user_controller_t *this,
+                                                       fast_request_t *request,
                                                        char *password, char *confirm)
 {
        if (!password || *password == '\0')
@@ -181,7 +182,7 @@ static bool verify_password(private_user_controller_t *this, request_t *request,
 /**
  * Register a user.
  */
-static void add(private_user_controller_t *this, request_t *request)
+static void add(private_user_controller_t *this, fast_request_t *request)
 {
        char *login = "";
 
@@ -222,7 +223,7 @@ static void add(private_user_controller_t *this, request_t *request)
 /**
  * Edit the logged in user
  */
-static void edit(private_user_controller_t *this, request_t *request)
+static void edit(private_user_controller_t *this, fast_request_t *request)
 {
        enumerator_t *query;
        char *old_login;
@@ -297,14 +298,14 @@ static void edit(private_user_controller_t *this, request_t *request)
        request->render(request, "templates/user/edit.cs");
 }
 
-METHOD(controller_t, get_name, char*,
+METHOD(fast_controller_t, get_name, char*,
        private_user_controller_t *this)
 {
        return "user";
 }
 
-METHOD(controller_t, handle, void,
-       private_user_controller_t *this, request_t *request, char *action,
+METHOD(fast_controller_t, handle, void,
+       private_user_controller_t *this, fast_request_t *request, char *action,
        char *p2, char *p3, char *p4, char *p5)
 {
        if (action)
@@ -333,7 +334,7 @@ METHOD(controller_t, handle, void,
        request->redirect(request, "user/login");
 }
 
-METHOD(controller_t, destroy, void,
+METHOD(fast_controller_t, destroy, void,
        private_user_controller_t *this)
 {
        free(this);
@@ -342,7 +343,7 @@ METHOD(controller_t, destroy, void,
 /*
  * see header file
  */
-controller_t *user_controller_create(user_t *user, database_t *db)
+fast_controller_t *user_controller_create(user_t *user, database_t *db)
 {
        private_user_controller_t *this;
 
@@ -362,4 +363,3 @@ controller_t *user_controller_create(user_t *user, database_t *db)
 
        return &this->public.controller;
 }
-
index 540dc74..8443a8d 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <user.h>
 
-#include <controller.h>
+#include <fast_controller.h>
 #include <database/database.h>
 
 typedef struct user_controller_t user_controller_t;
@@ -37,12 +37,12 @@ struct user_controller_t {
        /**
         * Implements controller_t interface.
         */
-       controller_t controller;
+       fast_controller_t controller;
 };
 
 /**
  * Create a user_controller controller instance.
  */
-controller_t *user_controller_create(user_t *user, database_t *db);
+fast_controller_t *user_controller_create(user_t *user, database_t *db);
 
 #endif /** USER_CONTROLLER_H_ @}*/
index 436a72f..fb39bdb 100644 (file)
@@ -40,8 +40,8 @@ struct private_auth_filter_t {
        database_t *db;
 };
 
-METHOD(filter_t, run, bool,
-       private_auth_filter_t *this, request_t *request, char *controller,
+METHOD(fast_filter_t, run, bool,
+       private_auth_filter_t *this, fast_request_t *request, char *controller,
        char *action, char *p2, char *p3, char *p4, char *p5)
 {
        if (this->user->get_user(this->user))
@@ -70,7 +70,7 @@ METHOD(filter_t, run, bool,
        return FALSE;
 }
 
-METHOD(filter_t, destroy, void,
+METHOD(fast_filter_t, destroy, void,
        private_auth_filter_t *this)
 {
        free(this);
@@ -79,7 +79,7 @@ METHOD(filter_t, destroy, void,
 /*
  * see header file
  */
-filter_t *auth_filter_create(user_t *user, database_t *db)
+fast_filter_t *auth_filter_create(user_t *user, database_t *db)
 {
        private_auth_filter_t *this;
 
@@ -96,4 +96,3 @@ filter_t *auth_filter_create(user_t *user, database_t *db)
 
        return &this->public.filter;
 }
-
index beae279..022254d 100644 (file)
@@ -23,7 +23,7 @@
 #define AUTH_FILTER_H_
 
 #include <library.h>
-#include <filter.h>
+#include <fast_filter.h>
 
 #include "user.h"
 
@@ -37,12 +37,12 @@ struct auth_filter_t {
        /**
         * Implements filter_t interface.
         */
-       filter_t filter;
+       fast_filter_t filter;
 };
 
 /**
  * Create a auth_filter instance.
  */
-filter_t *auth_filter_create(user_t *user, database_t *db);
+fast_filter_t *auth_filter_create(user_t *user, database_t *db);
 
 #endif /** AUTH_FILTER_H_  @}*/
index cbba728..6f08b97 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <stdio.h>
 
-#include <dispatcher.h>
+#include <fast_dispatcher.h>
 #include <utils/debug.h>
 #include <database/database.h>
 
@@ -26,7 +26,7 @@
 
 int main(int arc, char *argv[])
 {
-       dispatcher_t *dispatcher;
+       fast_dispatcher_t *dispatcher;
        database_t *db;
        char *socket;
        bool debug;
@@ -58,14 +58,14 @@ int main(int arc, char *argv[])
                return 1;
        }
 
-       dispatcher = dispatcher_create(socket, debug, timeout,
-                                                                  (context_constructor_t)user_create, db);
+       dispatcher = fast_dispatcher_create(socket, debug, timeout,
+                                       (fast_context_constructor_t)user_create, db);
        dispatcher->add_filter(dispatcher,
-                                               (filter_constructor_t)auth_filter_create, db);
+                                       (fast_filter_constructor_t)auth_filter_create, db);
        dispatcher->add_controller(dispatcher,
-                                               (controller_constructor_t)user_controller_create, db);
+                                       (fast_controller_constructor_t)user_controller_create, db);
        dispatcher->add_controller(dispatcher,
-                                               (controller_constructor_t)peer_controller_create, db);
+                                       (fast_controller_constructor_t)peer_controller_create, db);
 
        dispatcher->run(dispatcher, threads);
 
@@ -76,4 +76,3 @@ int main(int arc, char *argv[])
        library_deinit();
        return 0;
 }
-
index b485908..023dafb 100644 (file)
@@ -45,7 +45,7 @@ METHOD(user_t, get_user, u_int,
        return this->user;
 }
 
-METHOD(context_t, destroy, void,
+METHOD(fast_context_t, destroy, void,
        private_user_t *this)
 {
        free(this);
@@ -70,4 +70,3 @@ user_t *user_create(void *param)
 
        return &this->public;
 }
-
index beeed6e..475972a 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef USER_H_
 #define USER_H_
 
-#include <context.h>
+#include <fast_context.h>
 #include <library.h>
 
 typedef struct user_t user_t;
@@ -36,7 +36,7 @@ struct user_t {
        /**
         * implements context_t interface
         */
-       context_t context;
+       fast_context_t context;
 
        /**
         * Set the user ID of the logged in user.