4 * @brief Implementation of request_t.
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30 #include <ClearSilver/ClearSilver.h>
32 typedef struct private_request_t private_request_t
;
35 * private data of the task manager
37 struct private_request_t
{
45 * FastCGI request object
50 * ClearSilver CGI Kit context
55 * ClearSilver HDF dataset for this request
61 * thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
62 * ClearSilver cgiwrap is not threadsave, so we use a private
63 * context for each thread.
65 __thread FCGX_Request
*req
;
68 * length of param list in req->envp
70 __thread
int req_env_len
;
73 * fcgiwrap read callback
75 static int read_cb(void *null
, char *buf
, int size
)
77 return FCGX_GetStr(buf
, size
, req
->in
);
81 * fcgiwrap writef callback
83 static int writef_cb(void *null
, const char *format
, va_list args
)
85 FCGX_VFPrintF(req
->out
, format
, args
);
89 * fcgiwrap write callback
91 static int write_cb(void *null
, const char *buf
, int size
)
93 return FCGX_PutStr(buf
, size
, req
->out
);
97 * fcgiwrap getenv callback
99 static char *getenv_cb(void *null
, const char *key
)
103 value
= FCGX_GetParam(key
, req
->envp
);
104 return value ?
strdup(value
) : NULL
;
108 * fcgiwrap getenv callback
110 static int putenv_cb(void *null
, const char *key
, const char *value
)
117 * fcgiwrap iterenv callback
119 static int iterenv_cb(void *null
, int num
, char **key
, char **value
)
124 if (num
< req_env_len
)
128 eq
= strchr(req
->envp
[num
], '=');
131 *key
= strndup(req
->envp
[num
], eq
- req
->envp
[num
]);
132 *value
= strdup(eq
+ 1);
134 if (*key
== NULL
|| *value
== NULL
)
145 * Implementation of request_t.get_cookie.
147 static char* get_cookie(private_request_t
*this, char *name
)
149 return hdf_get_valuef(this->hdf
, "Cookie.%s", name
);
153 * Implementation of request_t.get_path.
155 static char* get_path(private_request_t
*this)
157 char * path
= FCGX_GetParam("PATH_INFO", this->req
->envp
);
158 return path ? path
: "";
162 * Implementation of request_t.get_post_data.
164 static char* get_query_data(private_request_t
*this, char *name
)
166 return hdf_get_valuef(this->hdf
, "Query.%s", name
);
170 * Implementation of request_t.add_cookie.
172 static void add_cookie(private_request_t
*this, char *name
, char *value
)
174 cgi_cookie_set (this->cgi
, name
, value
,
175 FCGX_GetParam("SCRIPT_NAME", this->req
->envp
),
180 * Implementation of request_t.redirect.
182 static void redirect(private_request_t
*this, char *location
)
184 FCGX_FPrintF(this->req
->out
, "Status: 303 See Other\n");
185 FCGX_FPrintF(this->req
->out
, "Location: %s%s%s\n\n",
186 FCGX_GetParam("SCRIPT_NAME", this->req
->envp
),
187 *location
== '/' ?
"" : "/", location
);
191 * Implementation of request_t.get_base.
193 static char* get_base(private_request_t
*this)
195 return FCGX_GetParam("SCRIPT_NAME", this->req
->envp
);
199 * Implementation of request_t.render.
201 static void render(private_request_t
*this, char *template)
205 err
= cgi_display(this->cgi
, template);
208 cgi_neo_error(this->cgi
, err
);
215 * Implementation of request_t.set.
217 static void set(private_request_t
*this, char *key
, char *value
)
219 hdf_set_value(this->hdf
, key
, value
);
223 * Implementation of request_t.setf.
225 static void setf(private_request_t
*this, char *format
, ...)
229 va_start(args
, format
);
230 hdf_set_valuevf(this->hdf
, format
, args
);
235 * Implementation of request_t.destroy
237 static void destroy(private_request_t
*this)
239 cgi_destroy(&this->cgi
);
246 request_t
*request_create(FCGX_Request
*request
, bool debug
)
249 static bool initialized
= FALSE
;
250 private_request_t
*this = malloc_thing(private_request_t
);
252 this->public.get_path
= (char*(*)(request_t
*))get_path
;
253 this->public.get_base
= (char*(*)(request_t
*))get_base
;
254 this->public.add_cookie
= (void(*)(request_t
*, char *name
, char *value
))add_cookie
;
255 this->public.get_cookie
= (char*(*)(request_t
*,char*))get_cookie
;
256 this->public.get_query_data
= (char*(*)(request_t
*, char *name
))get_query_data
;
257 this->public.redirect
= (void(*)(request_t
*, char *location
))redirect
;
258 this->public.render
= (void(*)(request_t
*,char*))render
;
259 this->public.set
= (void(*)(request_t
*, char *, char*))set
;
260 this->public.setf
= (void(*)(request_t
*, char *format
, ...))setf
;
261 this->public.destroy
= (void(*)(request_t
*))destroy
;
265 cgiwrap_init_emu(NULL
, read_cb
, writef_cb
, write_cb
,
266 getenv_cb
, putenv_cb
, iterenv_cb
);
273 while (req
->envp
[req_env_len
] != NULL
)
278 err
= hdf_init(&this->hdf
);
281 hdf_set_value(this->hdf
, "base", get_base(this));
282 hdf_set_value(this->hdf
, "Config.NoCache", "true");
285 hdf_set_value(this->hdf
, "Config.TimeFooter", "0");
286 hdf_set_value(this->hdf
, "Config.CompressionEnabled", "1");
287 hdf_set_value(this->hdf
, "Config.WhiteSpaceStrip", "2");
290 err
= cgi_init(&this->cgi
, this->hdf
);
293 err
= cgi_parse(this->cgi
);
296 return &this->public;
298 cgi_destroy(&this->cgi
);