summaryrefslogtreecommitdiff
path: root/src/libfast
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfast')
-rw-r--r--src/libfast/Makefile.am2
-rw-r--r--src/libfast/Makefile.in149
-rw-r--r--src/libfast/context.h2
-rw-r--r--src/libfast/controller.h6
-rw-r--r--src/libfast/dispatcher.c261
-rw-r--r--src/libfast/dispatcher.h34
-rw-r--r--src/libfast/filter.h4
-rw-r--r--src/libfast/request.c82
-rw-r--r--src/libfast/request.h36
-rw-r--r--src/libfast/session.c54
-rw-r--r--src/libfast/session.h12
11 files changed, 390 insertions, 252 deletions
diff --git a/src/libfast/Makefile.am b/src/libfast/Makefile.am
index 6104f335d..870dcd6f1 100644
--- a/src/libfast/Makefile.am
+++ b/src/libfast/Makefile.am
@@ -3,6 +3,6 @@ lib_LTLIBRARIES = libfast.la
libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
controller.h dispatcher.h request.c session.c filter.h
libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl -lz
+ -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
AM_CFLAGS = -rdynamic
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index 266898984..e5ed4a289 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/Makefile.in
@@ -1,8 +1,9 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -16,8 +17,9 @@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
@@ -35,27 +37,52 @@ host_triplet = @host@
subdir = src/libfast
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)"
-libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
libfast_la_DEPENDENCIES = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(am__DEPENDENCIES_1)
am_libfast_la_OBJECTS = dispatcher.lo request.lo session.lo
libfast_la_OBJECTS = $(am_libfast_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
+am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -103,25 +130,22 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
-IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
-LINUX_HEADERS = @LINUX_HEADERS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
@@ -133,11 +157,14 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
+RTLIB = @RTLIB@
RUBY = @RUBY@
RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
@@ -166,9 +193,9 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
-confdir = @confdir@
datadir = @datadir@
datarootdir = @datarootdir@
+default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -191,7 +218,7 @@ ipsecuser = @ipsecuser@
libdir = @libdir@
libexecdir = @libexecdir@
libstrongswan_plugins = @libstrongswan_plugins@
-linuxdir = @linuxdir@
+linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
@@ -199,6 +226,7 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
@@ -207,10 +235,12 @@ pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+random_device = @random_device@
resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
-simreader = @simreader@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
@@ -218,6 +248,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
lib_LTLIBRARIES = libfast.la
@@ -225,7 +256,7 @@ libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
controller.h dispatcher.h request.c session.c filter.h
libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl -lz
+ -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
AM_CFLAGS = -rdynamic
@@ -242,9 +273,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libfast/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libfast/Makefile
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libfast/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libfast/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -262,23 +293,28 @@ $(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ list2="$$list2 $$p"; \
else :; fi; \
- done
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
@@ -304,21 +340,21 @@ distclean-compile:
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
@@ -341,7 +377,7 @@ tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
+ set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -349,29 +385,34 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
+ $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -392,13 +433,17 @@ distdir: $(DISTFILES)
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@@ -429,6 +474,7 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -450,6 +496,8 @@ dvi-am:
html: html-am
+html-am:
+
info: info-am
info-am:
@@ -458,18 +506,28 @@ install-data-am:
install-dvi: install-dvi-am
+install-dvi-am:
+
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
+install-html-am:
+
install-info: install-info-am
+install-info-am:
+
install-man:
install-pdf: install-pdf-am
+install-pdf-am:
+
install-ps: install-ps-am
+install-ps-am:
+
installcheck-am:
maintainer-clean: maintainer-clean-am
@@ -508,6 +566,7 @@ uninstall-am: uninstall-libLTLIBRARIES
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/libfast/context.h b/src/libfast/context.h
index 48b3c5e23..4f8d11d2c 100644
--- a/src/libfast/context.h
+++ b/src/libfast/context.h
@@ -32,7 +32,7 @@ typedef context_t *(*context_constructor_t)(void *param);
* User specific session context, to extend.
*/
struct context_t {
-
+
/**
* Destroy the context_t.
*/
diff --git a/src/libfast/controller.h b/src/libfast/controller.h
index 55ba6f58a..1edf72e90 100644
--- a/src/libfast/controller.h
+++ b/src/libfast/controller.h
@@ -42,14 +42,14 @@ typedef controller_t *(*controller_constructor_t)(context_t* context, void *para
* 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.
*
@@ -67,7 +67,7 @@ struct controller_t {
*/
void (*handle)(controller_t *this, request_t *request,
char *p1, char *p2, char *p3, char *p4, char *p5);
-
+
/**
* Destroy the controller instance.
*/
diff --git a/src/libfast/dispatcher.c b/src/libfast/dispatcher.c
index 35ae55814..7690230d3 100644
--- a/src/libfast/dispatcher.c
+++ b/src/libfast/dispatcher.c
@@ -19,12 +19,18 @@
#include "session.h"
#include <fcgiapp.h>
-#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <debug.h>
+#include <threading/thread.h>
+#include <threading/condvar.h>
+#include <threading/mutex.h>
#include <utils/linked_list.h>
+#include <utils/hashtable.h>
+
+/** Intervall to check for expired sessions, in seconds */
+#define CLEANUP_INTERVAL 30
typedef struct private_dispatcher_t private_dispatcher_t;
@@ -37,57 +43,62 @@ struct private_dispatcher_t {
* public functions
*/
dispatcher_t public;
-
+
/**
* fcgi socket fd
*/
int fd;
-
+
/**
* thread list
*/
- pthread_t *threads;
-
+ thread_t **threads;
+
/**
* number of threads in "threads"
*/
int thread_count;
-
+
/**
* session locking mutex
*/
- pthread_mutex_t mutex;
-
+ mutex_t *mutex;
+
/**
- * List of sessions
+ * Hahstable with active sessions
*/
- linked_list_t *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
*/
@@ -112,7 +123,7 @@ typedef struct {
/** session instance */
session_t *session;
/** condvar to wait for session */
- pthread_cond_t cond;
+ condvar_t *cond;
/** client host address, to prevent session hijacking */
char *host;
/** TRUE if session is in use */
@@ -128,36 +139,36 @@ typedef struct {
*/
static session_t* load_session(private_dispatcher_t *this)
{
- iterator_t *iterator;
+ 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);
-
- iterator = this->controllers->create_iterator(this->controllers, TRUE);
- while (iterator->iterate(iterator, (void**)&centry))
+
+ enumerator = this->controllers->create_enumerator(this->controllers);
+ while (enumerator->enumerate(enumerator, &centry))
{
controller = centry->constructor(context, centry->param);
session->add_controller(session, controller);
}
- iterator->destroy(iterator);
-
- iterator = this->filters->create_iterator(this->filters, TRUE);
- while (iterator->iterate(iterator, (void**)&fentry))
+ 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);
}
- iterator->destroy(iterator);
-
+ enumerator->destroy(enumerator);
+
return session;
}
@@ -168,21 +179,25 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this,
char *host)
{
session_entry_t *entry;
-
+
entry = malloc_thing(session_entry_t);
entry->in_use = FALSE;
entry->closed = FALSE;
- pthread_cond_init(&entry->cond, NULL);
+ entry->cond = condvar_create(CONDVAR_TYPE_DEFAULT);
entry->session = load_session(this);
- entry->used = time(NULL);
+ entry->used = time_monotonic(NULL);
entry->host = strdup(host);
-
+
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);
}
@@ -194,7 +209,7 @@ static void add_controller(private_dispatcher_t *this,
controller_constructor_t constructor, void *param)
{
controller_entry_t *entry = malloc_thing(controller_entry_t);
-
+
entry->constructor = constructor;
entry->param = param;
this->controllers->insert_last(this->controllers, entry);
@@ -207,90 +222,129 @@ static void add_filter(private_dispatcher_t *this,
filter_constructor_t constructor, void *param)
{
filter_entry_t *entry = malloc_thing(filter_entry_t);
-
+
entry->constructor = constructor;
entry->param = param;
this->filters->insert_last(this->filters, entry);
}
/**
- * Actual dispatching code
+ * 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)
{
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ thread_cancelability(FALSE);
while (TRUE)
{
request_t *request;
- session_entry_t *current, *found = NULL;
- iterator_t *iterator;
+ session_entry_t *found = NULL;
time_t now;
char *sid;
-
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+ thread_cancelability(TRUE);
request = request_create(this->fd, this->debug);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ thread_cancelability(FALSE);
if (request == NULL)
{
continue;
}
+ now = time_monotonic(NULL);
sid = request->get_cookie(request, "SID");
- now = time(NULL);
-
- /* find session */
- pthread_mutex_lock(&this->mutex);
- iterator = this->sessions->create_iterator(this->sessions, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+
+ this->mutex->lock(this->mutex);
+ if (sid)
{
- /* check all sessions for timeout or close flag
- * TODO: use a seperate cleanup thread */
- if (!current->in_use &&
- (current->used < now - this->timeout || current->closed))
- {
- iterator->remove(iterator);
- session_entry_destroy(current);
- continue;
- }
- /* find by session ID. Prevent session hijacking by host check */
- if (!found && sid &&
- streq(current->session->get_sid(current->session), sid) &&
- streq(current->host, request->get_host(request)))
- {
- found = current;
- }
+ found = this->sessions->get(this->sessions, sid);
+ }
+ if (found && !streq(found->host, request->get_host(request)))
+ {
+ found = NULL;
}
- iterator->destroy(iterator);
-
if (found)
{
/* wait until session is unused */
while (found->in_use)
{
- pthread_cond_wait(&found->cond, &this->mutex);
+ found->cond->wait(found->cond, this->mutex);
}
}
else
{ /* create a new session if not found */
found = session_entry_create(this, request->get_host(request));
- this->sessions->insert_first(this->sessions, found);
+ sid = found->session->get_sid(found->session);
+ this->sessions->put(this->sessions, sid, found);
}
found->in_use = TRUE;
- pthread_mutex_unlock(&this->mutex);
-
+ this->mutex->unlock(this->mutex);
+
/* start processing */
found->session->process(found->session, request);
- found->used = time(NULL);
-
+ found->used = time_monotonic(NULL);
+
/* release session */
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
found->in_use = FALSE;
found->closed = request->session_closed(request);
- pthread_cond_signal(&found->cond);
- pthread_mutex_unlock(&this->mutex);
-
- /* cleanup */
+ found->cond->signal(found->cond);
+ cleanup_sessions(this, now);
+ this->mutex->unlock(this->mutex);
+
request->destroy(request);
}
}
@@ -301,11 +355,12 @@ static void dispatch(private_dispatcher_t *this)
static void run(private_dispatcher_t *this, int threads)
{
this->thread_count = threads;
- this->threads = malloc(sizeof(pthread_t) * threads);
+ this->threads = malloc(sizeof(thread_t*) * threads);
while (threads)
{
- if (pthread_create(&this->threads[threads - 1],
- NULL, (void*)dispatch, this) == 0)
+ this->threads[threads - 1] = thread_create((thread_main_t)dispatch,
+ this);
+ if (this->threads[threads - 1])
{
threads--;
}
@@ -319,7 +374,7 @@ static void waitsignal(private_dispatcher_t *this)
{
sigset_t set;
int sig;
-
+
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
@@ -333,15 +388,27 @@ static void waitsignal(private_dispatcher_t *this)
*/
static void destroy(private_dispatcher_t *this)
{
+ char *sid;
+ session_entry_t *entry;
+ enumerator_t *enumerator;
+
FCGX_ShutdownPending();
while (this->thread_count--)
{
- pthread_cancel(this->threads[this->thread_count]);
- pthread_join(this->threads[this->thread_count], NULL);
+ 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);
}
- this->sessions->destroy_function(this->sessions, (void*)session_entry_destroy);
+ 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);
}
@@ -359,22 +426,24 @@ dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
this->public.run = (void(*)(dispatcher_t*, int threads))run;
this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
this->public.destroy = (void(*)(dispatcher_t*))destroy;
-
- this->sessions = linked_list_create();
+
+ this->sessions = hashtable_create((void*)session_hash,
+ (void*)session_equals, 4096);
this->controllers = linked_list_create();
this->filters = linked_list_create();
this->context_constructor = constructor;
- pthread_mutex_init(&this->mutex, NULL);
+ this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
this->param = param;
- this->fd = 0;
- this->timeout = timeout;
- this->debug = debug;
- this->threads = NULL;
-
- FCGX_Init();
-
- if (socket)
- {
+ this->fd = 0;
+ this->timeout = timeout;
+ this->last_cleanup = time_monotonic(NULL);
+ this->debug = debug;
+ this->threads = NULL;
+
+ FCGX_Init();
+
+ if (socket)
+ {
unlink(socket);
this->fd = FCGX_OpenSocket(socket, 10);
}
diff --git a/src/libfast/dispatcher.h b/src/libfast/dispatcher.h
index 5b4e3f947..16223fe76 100644
--- a/src/libfast/dispatcher.h
+++ b/src/libfast/dispatcher.h
@@ -23,33 +23,33 @@
* 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
+ * 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
+ * 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
+ * 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,
+
+ 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
@@ -76,7 +76,7 @@ typedef struct dispatcher_t dispatcher_t;
* constructor added with add_controller.
*/
struct dispatcher_t {
-
+
/**
* Register a controller to the dispatcher.
*
@@ -90,14 +90,14 @@ struct dispatcher_t {
controller_constructor_t constructor, void *param);
/**
- * @brief Add a filter to the dispatcher.
+ * 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);
-
+ filter_constructor_t constructor, void *param);
+
/**
* Start with dispatching.
*
@@ -106,13 +106,13 @@ struct dispatcher_t {
* @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.
*/
diff --git a/src/libfast/filter.h b/src/libfast/filter.h
index d2602db9d..305a8bb6e 100644
--- a/src/libfast/filter.h
+++ b/src/libfast/filter.h
@@ -39,7 +39,7 @@ 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.
*
@@ -53,7 +53,7 @@ struct filter_t {
*/
bool (*run)(filter_t *this, request_t *request,
char *p0, char *p1, char *p2, char *p3, char *p4, char *p5);
-
+
/**
* Destroy the filter instance.
*/
diff --git a/src/libfast/request.c b/src/libfast/request.c
index 96dfab8e7..3f4894c45 100644
--- a/src/libfast/request.c
+++ b/src/libfast/request.c
@@ -20,10 +20,13 @@
#include <library.h>
#include <debug.h>
#include <stdlib.h>
-#include <string.h>
#include <pthread.h>
+#include <string.h>
#include <ClearSilver/ClearSilver.h>
+#include <threading/thread.h>
+#include <threading/thread_value.h>
+
typedef struct private_request_t private_request_t;
/**
@@ -35,32 +38,32 @@ 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
*/
@@ -68,11 +71,10 @@ struct private_request_t {
};
/**
- * key to a the threads "this" request, used for ClearSilver cgiwrap callbacks.
* ClearSilver cgiwrap is not threadsave, so we use a private
* context for each thread.
*/
-static pthread_key_t this_key;
+static thread_value_t *thread_this;
/**
* control variable for pthread_once
@@ -84,8 +86,8 @@ pthread_once_t once = PTHREAD_ONCE_INIT;
*/
static int read_cb(void *null, char *buf, int size)
{
- private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
-
+ private_request_t *this = (private_request_t*)thread_this->get(thread_this);
+
return FCGX_GetStr(buf, size, this->req.in);
}
@@ -94,8 +96,8 @@ static int read_cb(void *null, char *buf, int size)
*/
static int writef_cb(void *null, const char *format, va_list args)
{
- private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
-
+ private_request_t *this = (private_request_t*)thread_this->get(thread_this);
+
FCGX_VFPrintF(this->req.out, format, args);
return 0;
}
@@ -104,8 +106,8 @@ static int writef_cb(void *null, const char *format, va_list args)
*/
static int write_cb(void *null, const char *buf, int size)
{
- private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
-
+ private_request_t *this = (private_request_t*)thread_this->get(thread_this);
+
return FCGX_PutStr(buf, size, this->req.out);
}
@@ -115,8 +117,8 @@ static int write_cb(void *null, const char *buf, int size)
static char *getenv_cb(void *null, const char *key)
{
char *value;
- private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
-
+ private_request_t *this = (private_request_t*)thread_this->get(thread_this);
+
value = FCGX_GetParam(key, this->req.envp);
return value ? strdup(value) : NULL;
}
@@ -137,7 +139,7 @@ static int iterenv_cb(void *null, int num, char **key, char **value)
{
*key = NULL;
*value = NULL;
- private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+ private_request_t *this = (private_request_t*)thread_this->get(thread_this);
if (num < this->req_env_len)
{
char *eq;
@@ -157,7 +159,7 @@ static int iterenv_cb(void *null, int num, char **key, char **value)
}
return 0;
}
-
+
/**
* Implementation of request_t.get_cookie.
*/
@@ -165,7 +167,7 @@ static char* get_cookie(private_request_t *this, char *name)
{
return hdf_get_valuef(this->hdf, "Cookie.%s", name);
}
-
+
/**
* Implementation of request_t.get_path.
*/
@@ -206,12 +208,12 @@ static char* get_query_data(private_request_t *this, char *name)
*/
static void add_cookie(private_request_t *this, char *name, char *value)
{
- pthread_setspecific(this_key, this);
+ thread_this->set(thread_this, this);
cgi_cookie_set (this->cgi, name, value,
FCGX_GetParam("SCRIPT_NAME", this->req.envp),
NULL, NULL, 0, 0);
}
-
+
/**
* Implementation of request_t.redirect.
*/
@@ -246,7 +248,7 @@ static char* get_base(private_request_t *this)
{
return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
}
-
+
/**
* Implementation of request_t.session_closed.
*/
@@ -279,8 +281,8 @@ static void serve(private_request_t *this, char *headers, chunk_t chunk)
static void render(private_request_t *this, char *template)
{
NEOERR* err;
-
- pthread_setspecific(this_key, this);
+
+ thread_this->set(thread_this, this);
err = cgi_display(this->cgi, template);
if (err)
{
@@ -327,8 +329,8 @@ static void setf(private_request_t *this, char *format, ...)
va_start(args, format);
hdf_set_valuevf(this->hdf, format, args);
va_end(args);
-}
-
+}
+
/**
* Implementation of request_t.get_ref.
*/
@@ -345,7 +347,7 @@ static void destroy(private_request_t *this)
{
if (ref_put(&this->ref))
{
- pthread_setspecific(this_key, this);
+ thread_this->set(thread_this, this);
cgi_destroy(&this->cgi);
FCGX_Finish_r(&this->req);
free(this);
@@ -359,8 +361,8 @@ static void destroy(private_request_t *this)
static void init(void)
{
cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
- getenv_cb, putenv_cb, iterenv_cb);
- pthread_key_create(&this_key, NULL);
+ getenv_cb, putenv_cb, iterenv_cb);
+ thread_this = thread_value_create(NULL);
}
/*
@@ -371,14 +373,14 @@ request_t *request_create(int fd, bool debug)
NEOERR* err;
private_request_t *this = malloc_thing(private_request_t);
bool failed = FALSE;
-
- pthread_cleanup_push(free, this);
+
+ thread_cleanup_push(free, this);
if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
FCGX_Accept_r(&this->req) != 0)
{
failed = TRUE;
}
- pthread_cleanup_pop(failed);
+ thread_cleanup_pop(failed);
if (failed)
{
return NULL;
@@ -402,18 +404,18 @@ request_t *request_create(int fd, bool debug)
this->public.setf = (void(*)(request_t*, char *format, ...))setf;
this->public.get_ref = (request_t*(*)(request_t*))get_ref;
this->public.destroy = (void(*)(request_t*))destroy;
-
+
pthread_once(&once, init);
- pthread_setspecific(this_key, this);
-
+ thread_this->set(thread_this, this);
+
this->ref = 1;
this->closed = FALSE;
- this->req_env_len = 0;
+ this->req_env_len = 0;
while (this->req.envp[this->req_env_len] != NULL)
{
this->req_env_len++;
}
-
+
err = hdf_init(&this->hdf);
if (!err)
{
@@ -425,7 +427,7 @@ request_t *request_create(int fd, bool debug)
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)
{
diff --git a/src/libfast/request.h b/src/libfast/request.h
index b9ea88830..61e2d59f0 100644
--- a/src/libfast/request.h
+++ b/src/libfast/request.h
@@ -32,7 +32,7 @@ typedef struct request_t request_t;
* The response is also handled through the request object.
*/
struct request_t {
-
+
/**
* Add a cookie to the reply (Set-Cookie header).
*
@@ -40,7 +40,7 @@ struct request_t {
* @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.
*
@@ -48,35 +48,35 @@ struct request_t {
* @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.
*
@@ -84,19 +84,19 @@ struct request_t {
* @return value, NULL if not found
*/
char* (*get_query_data)(request_t *this, char *name);
-
+
/**
* 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.
*
@@ -104,12 +104,12 @@ struct request_t {
* @param ... variable argument for fmt
*/
void (*redirect)(request_t *this, char *fmt, ...);
-
+
/**
* Redirect the client to the referer.
*/
void (*to_referer)(request_t *this);
-
+
/**
* Set a template value.
*
@@ -117,7 +117,7 @@ struct request_t {
* @param value value to set key to
*/
void (*set)(request_t *this, char *key, char *value);
-
+
/**
* Set a template value using format strings.
*
@@ -128,7 +128,7 @@ struct request_t {
* @param ... variable argument list
*/
void (*setf)(request_t *this, char *format, ...);
-
+
/**
* Render a template.
*
@@ -139,7 +139,7 @@ struct request_t {
* @param template clearsilver template file location
*/
void (*render)(request_t *this, char *template);
-
+
/**
* Stream a format string to the client.
*
@@ -151,7 +151,7 @@ struct request_t {
* @return number of streamed bytes, < 0 if stream closed
*/
int (*streamf)(request_t *this, char *format, ...);
-
+
/**
* Serve a request with headers and a body.
*
@@ -159,14 +159,14 @@ struct request_t {
* @param chunk body to write to output
*/
void (*serve)(request_t *this, char *headers, chunk_t chunk);
-
+
/**
* Increase the reference count to the stream.
*
* @return this with increased refcount
*/
request_t* (*get_ref)(request_t *this);
-
+
/**
* Destroy the request_t.
*/
diff --git a/src/libfast/session.c b/src/libfast/session.c
index 455c8d5e1..f03b75542 100644
--- a/src/libfast/session.c
+++ b/src/libfast/session.c
@@ -23,6 +23,8 @@
#include <utils/linked_list.h>
+#define COOKIE_LEN 16
+
typedef struct private_session_t private_session_t;
/**
@@ -34,22 +36,27 @@ struct private_session_t {
* public functions
*/
session_t public;
-
+
/**
* session ID
*/
- char *sid;
-
+ 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
*/
@@ -75,20 +82,20 @@ static void add_filter(private_session_t *this, filter_t *filter)
/**
* Create a session ID and a cookie
*/
-static void create_sid(private_session_t *this, request_t *request)
+static void create_sid(private_session_t *this)
{
- char buf[16];
- chunk_t chunk = chunk_from_buf(buf);
+ char buf[COOKIE_LEN];
rng_t *rng;
-
+
+ memset(buf, 0, sizeof(buf));
+ memset(this->sid, 0, sizeof(this->sid));
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (rng)
{
rng->get_bytes(rng, sizeof(buf), buf);
- this->sid = chunk_to_hex(chunk, NULL, FALSE).ptr;
- request->add_cookie(request, "SID", this->sid);
rng->destroy(rng);
}
+ chunk_to_hex(chunk_create(buf, sizeof(buf)), this->sid, FALSE);
}
/**
@@ -99,7 +106,7 @@ static bool run_filter(private_session_t *this, request_t *request, char *p0,
{
enumerator_t *enumerator;
filter_t *filter;
-
+
enumerator = this->filters->create_enumerator(this->filters);
while (enumerator->enumerate(enumerator, &filter))
{
@@ -123,12 +130,13 @@ static void process(private_session_t *this, request_t *request)
bool handled = FALSE;
controller_t *current;
int i = 0;
-
- if (this->sid == NULL)
+
+ if (!this->cookie_sent)
{
- create_sid(this, request);
+ request->add_cookie(request, "SID", this->sid);
+ this->cookie_sent = TRUE;
}
-
+
start = request->get_path(request);
if (start)
{
@@ -142,15 +150,15 @@ static void process(private_session_t *this, request_t *request)
start = pos + 1;
}
param[i] = strdupa(start);
-
- if (run_filter(this, request, param[0], param[1], param[2], param[3],
- param[4], param[5]))
+
+ 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;
@@ -190,7 +198,6 @@ static void destroy(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->sid);
free(this);
}
@@ -207,11 +214,12 @@ session_t *session_create(context_t *context)
this->public.get_sid = (char*(*)(session_t*))get_sid;
this->public.destroy = (void(*)(session_t*))destroy;
- this->sid = NULL;
+ create_sid(this);
+ this->cookie_sent = FALSE;
this->controllers = linked_list_create();
this->filters = linked_list_create();
this->context = context;
-
+
return &this->public;
}
diff --git a/src/libfast/session.h b/src/libfast/session.h
index 524e60f46..c6633f9ae 100644
--- a/src/libfast/session.h
+++ b/src/libfast/session.h
@@ -31,35 +31,35 @@ 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);
-
+
/**
- * @brief Add a filter instance to the session.
+ * 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.
*