diff options
Diffstat (limited to 'src/libfast/request.c')
-rw-r--r-- | src/libfast/request.c | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/src/libfast/request.c b/src/libfast/request.c deleted file mode 100644 index 3acd831b2..000000000 --- a/src/libfast/request.c +++ /dev/null @@ -1,439 +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 <debug.h> -#include <stdlib.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; - -/** - * 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, 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, - .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; -} - |