request_t.redirect takes variable argument list
authorMartin Willi <martin@strongswan.org>
Fri, 19 Oct 2007 19:40:53 +0000 (19:40 -0000)
committerMartin Willi <martin@strongswan.org>
Fri, 19 Oct 2007 19:40:53 +0000 (19:40 -0000)
request_t.serve to serve non-template data
fixed dispatcher thread locking code

src/manager/lib/dispatcher.c
src/manager/lib/request.c
src/manager/lib/request.h

index df669ce..ce53d39 100644 (file)
@@ -30,6 +30,7 @@
 #include <signal.h>
 #include <unistd.h>
 
+#include <debug.h>
 #include <utils/linked_list.h>
 
 typedef struct private_dispatcher_t private_dispatcher_t;
@@ -122,8 +123,8 @@ typedef struct {
        session_t *session;
        /** condvar to wait for session */
        pthread_cond_t cond;
-       /** number of threads waiting for session */
-       int waiting;
+       /** TRUE if session is in use */
+       bool in_use;
        /** last use of the session */
        time_t used;
 } session_entry_t;
@@ -164,7 +165,7 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this)
        session_entry_t *entry;
        
        entry = malloc_thing(session_entry_t);
-       entry->waiting = 1;
+       entry->in_use = FALSE;
        pthread_cond_init(&entry->cond, NULL);
        entry->session = load_session(this);
        entry->used = time(NULL);
@@ -228,11 +229,12 @@ static void dispatch(private_dispatcher_t *this)
                        now = time(NULL);
                        
                        /* find session */
-                       iterator = this->sessions->create_iterator_locked(this->sessions, &this->mutex);
+                       pthread_mutex_lock(&this->mutex);
+                       iterator = this->sessions->create_iterator(this->sessions, TRUE);
                        while (iterator->iterate(iterator, (void**)&current))
                        {
                                /* check all sessions for timeout */
-                               if (current->waiting == 0 &&
+                               if (!current->in_use &&
                                        current->used < now - this->timeout)
                                {
                                        iterator->remove(iterator);
@@ -243,27 +245,24 @@ static void dispatch(private_dispatcher_t *this)
                                        streq(current->session->get_sid(current->session), sid))
                                {
                                        found = current;
-                                       found->waiting++;
                                }
                        }
                        iterator->destroy(iterator);
                        
                        if (found)
                        {       /* wait until session is unused */
-                               pthread_mutex_lock(&this->mutex);
-                               while (found->waiting > 1)
+                               while (found->in_use)
                                {
                                        pthread_cond_wait(&found->cond, &this->mutex);
                                }
-                               pthread_mutex_unlock(&this->mutex);
                        }
                        else
                        {       /* create a new session if not found */
                                found = session_entry_create(this);
-                               pthread_mutex_lock(&this->mutex);
                                this->sessions->insert_first(this->sessions, found);
-                               pthread_mutex_unlock(&this->mutex);
                        }
+                       found->in_use = TRUE;
+                       pthread_mutex_unlock(&this->mutex);
                
                        /* start processing */
                        found->session->process(found->session, request);
@@ -271,7 +270,7 @@ static void dispatch(private_dispatcher_t *this)
                        
                        /* release session */
                        pthread_mutex_lock(&this->mutex);
-                       found->waiting--;
+                       found->in_use = FALSE;
                        pthread_cond_signal(&found->cond);
                        pthread_mutex_unlock(&this->mutex);
                        
index 4623b38..2e18bde 100644 (file)
@@ -179,12 +179,18 @@ static void add_cookie(private_request_t *this, char *name, char *value)
 /**
  * Implementation of request_t.redirect.
  */
-static void redirect(private_request_t *this, char *location)
+static void redirect(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%s\n\n",
+       FCGX_FPrintF(this->req->out, "Location: %s%s",
                                 FCGX_GetParam("SCRIPT_NAME", this->req->envp),
-                                *location == '/' ? "" : "/", location);
+                                *fmt == '/' ? "" : "/");
+       va_start(args, fmt);
+       FCGX_VFPrintF(this->req->out, fmt, args);
+       va_end(args);
+       FCGX_FPrintF(this->req->out, "\n\n");
 }
 
 /**
@@ -196,6 +202,16 @@ static char* get_base(private_request_t *this)
 }
 
 /**
+ * Implementation of request_t.serve.
+ */
+static void serve(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);
+}
+
+/**
  * Implementation of request_t.render.
  */
 static void render(private_request_t *this, char *template)
@@ -254,8 +270,9 @@ request_t *request_create(FCGX_Request *request, bool debug)
        this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
        this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
        this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
-       this->public.redirect = (void(*)(request_t*, char *location))redirect;
+       this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
        this->public.render = (void(*)(request_t*,char*))render;
+       this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
        this->public.set = (void(*)(request_t*, char *, char*))set;
        this->public.setf = (void(*)(request_t*, char *format, ...))setf;
        this->public.destroy = (void(*)(request_t*))destroy;
index e6fd71e..f78741d 100644 (file)
@@ -75,9 +75,10 @@ struct request_t {
        /**
         * @brief Redirect the client to another location.
         *
-        * @param location              location to redirect to
+        * @param fmt           location format string
+        * @param ...           variable argument for fmt
         */
-       void (*redirect)(request_t *this, char *location);
+       void (*redirect)(request_t *this, char *fmt, ...);
        
        /**
         * @brief Set a template value.
@@ -106,11 +107,18 @@ struct request_t {
         * other targets without to worry about path location.
         *
         * @param template      clearsilver template file location
-        * @return                      rendered template string
         */
        void (*render)(request_t *this, char *template);
        
        /**
+        * @brief 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);
+       
+       /**
         * @brief Destroy the request_t.
         */
        void (*destroy) (request_t *this);