Annotation of embedaddon/lighttpd/src/mod_cml.c, revision 1.1.1.3
1.1.1.3 ! misho 1: #include "first.h"
! 2:
1.1 misho 3: #include "buffer.h"
4: #include "server.h"
5: #include "log.h"
6: #include "plugin.h"
7: #include "response.h"
8:
9: #include "stream.h"
10:
11: #include "mod_cml.h"
12:
13: #include <sys/stat.h>
14: #include <time.h>
15:
16: #include <stdlib.h>
17: #include <string.h>
18: #include <errno.h>
19: #include <unistd.h>
20: #include <stdio.h>
21:
22: /* init the plugin data */
23: INIT_FUNC(mod_cml_init) {
24: plugin_data *p;
25:
26: p = calloc(1, sizeof(*p));
27:
28: p->basedir = buffer_init();
29: p->baseurl = buffer_init();
30: p->trigger_handler = buffer_init();
31:
32: return p;
33: }
34:
35: /* detroy the plugin data */
36: FREE_FUNC(mod_cml_free) {
37: plugin_data *p = p_d;
38:
39: UNUSED(srv);
40:
41: if (!p) return HANDLER_GO_ON;
42:
43: if (p->config_storage) {
44: size_t i;
45: for (i = 0; i < srv->config_context->used; i++) {
46: plugin_config *s = p->config_storage[i];
47:
1.1.1.3 ! misho 48: if (NULL == s) continue;
! 49:
1.1 misho 50: buffer_free(s->ext);
51:
52: buffer_free(s->mc_namespace);
53: buffer_free(s->power_magnet);
54: array_free(s->mc_hosts);
55:
1.1.1.3 ! misho 56: #if defined(USE_MEMCACHED)
! 57: if (s->memc) memcached_free(s->memc);
1.1 misho 58: #endif
59:
60: free(s);
61: }
62: free(p->config_storage);
63: }
64:
65: buffer_free(p->trigger_handler);
66: buffer_free(p->basedir);
67: buffer_free(p->baseurl);
68:
69: free(p);
70:
71: return HANDLER_GO_ON;
72: }
73:
74: /* handle plugin config and check values */
75:
76: SETDEFAULTS_FUNC(mod_cml_set_defaults) {
77: plugin_data *p = p_d;
78: size_t i = 0;
79:
80: config_values_t cv[] = {
81: { "cml.extension", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
82: { "cml.memcache-hosts", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
83: { "cml.memcache-namespace", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
84: { "cml.power-magnet", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
85: { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
86: };
87:
88: if (!p) return HANDLER_ERROR;
89:
1.1.1.2 misho 90: p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
1.1 misho 91:
92: for (i = 0; i < srv->config_context->used; i++) {
1.1.1.3 ! misho 93: data_config const* config = (data_config const*)srv->config_context->data[i];
1.1 misho 94: plugin_config *s;
95:
96: s = malloc(sizeof(plugin_config));
97: s->ext = buffer_init();
98: s->mc_hosts = array_init();
99: s->mc_namespace = buffer_init();
100: s->power_magnet = buffer_init();
1.1.1.3 ! misho 101: #if defined(USE_MEMCACHED)
! 102: s->memc = NULL;
1.1 misho 103: #endif
104:
105: cv[0].destination = s->ext;
106: cv[1].destination = s->mc_hosts;
107: cv[2].destination = s->mc_namespace;
108: cv[3].destination = s->power_magnet;
109:
110: p->config_storage[i] = s;
111:
1.1.1.3 ! misho 112: if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
1.1 misho 113: return HANDLER_ERROR;
114: }
115:
116: if (s->mc_hosts->used) {
1.1.1.3 ! misho 117: #if defined(USE_MEMCACHED)
! 118: buffer *option_string = buffer_init();
1.1 misho 119: size_t k;
120:
1.1.1.3 ! misho 121: {
! 122: data_string *ds = (data_string *)s->mc_hosts->data[0];
! 123:
! 124: buffer_append_string_len(option_string, CONST_STR_LEN("--SERVER="));
! 125: buffer_append_string_buffer(option_string, ds->value);
! 126: }
! 127:
! 128: for (k = 1; k < s->mc_hosts->used; k++) {
1.1 misho 129: data_string *ds = (data_string *)s->mc_hosts->data[k];
130:
1.1.1.3 ! misho 131: buffer_append_string_len(option_string, CONST_STR_LEN(" --SERVER="));
! 132: buffer_append_string_buffer(option_string, ds->value);
! 133: }
! 134:
! 135: s->memc = memcached(CONST_BUF_LEN(option_string));
1.1 misho 136:
1.1.1.3 ! misho 137: if (NULL == s->memc) {
! 138: log_error_write(srv, __FILE__, __LINE__, "sb",
! 139: "configuring memcached failed for option string:",
! 140: option_string);
1.1 misho 141: }
1.1.1.3 ! misho 142: buffer_free(option_string);
! 143:
! 144: if (NULL == s->memc) return HANDLER_ERROR;
1.1 misho 145: #else
146: log_error_write(srv, __FILE__, __LINE__, "s",
1.1.1.3 ! misho 147: "memcache support is not compiled in but cml.memcache-hosts is set, aborting");
1.1 misho 148: return HANDLER_ERROR;
149: #endif
150: }
151: }
152:
153: return HANDLER_GO_ON;
154: }
155:
156: #define PATCH(x) \
157: p->conf.x = s->x;
158: static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) {
159: size_t i, j;
160: plugin_config *s = p->config_storage[0];
161:
162: PATCH(ext);
1.1.1.3 ! misho 163: #if defined(USE_MEMCACHED)
! 164: PATCH(memc);
1.1 misho 165: #endif
166: PATCH(mc_namespace);
167: PATCH(power_magnet);
168:
169: /* skip the first, the global context */
170: for (i = 1; i < srv->config_context->used; i++) {
171: data_config *dc = (data_config *)srv->config_context->data[i];
172: s = p->config_storage[i];
173:
174: /* condition didn't match */
175: if (!config_check_cond(srv, con, dc)) continue;
176:
177: /* merge config */
178: for (j = 0; j < dc->value->used; j++) {
179: data_unset *du = dc->value->data[j];
180:
181: if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) {
182: PATCH(ext);
183: } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) {
1.1.1.3 ! misho 184: #if defined(USE_MEMCACHED)
! 185: PATCH(memc);
1.1 misho 186: #endif
187: } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) {
188: PATCH(mc_namespace);
189: } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) {
190: PATCH(power_magnet);
191: }
192: }
193: }
194:
195: return 0;
196: }
197: #undef PATCH
198:
199: static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
200: buffer *b;
201: char *c;
202:
203: /* cleanup basedir */
204: b = p->baseurl;
1.1.1.3 ! misho 205: buffer_copy_buffer(b, con->uri.path);
! 206: for (c = b->ptr + buffer_string_length(b); c > b->ptr && *c != '/'; c--);
1.1 misho 207:
208: if (*c == '/') {
1.1.1.3 ! misho 209: buffer_string_set_length(b, c - b->ptr + 1);
1.1 misho 210: }
211:
212: b = p->basedir;
1.1.1.3 ! misho 213: buffer_copy_buffer(b, con->physical.path);
! 214: for (c = b->ptr + buffer_string_length(b); c > b->ptr && *c != '/'; c--);
1.1 misho 215:
216: if (*c == '/') {
1.1.1.3 ! misho 217: buffer_string_set_length(b, c - b->ptr + 1);
1.1 misho 218: }
219:
220:
221: /* prepare variables
222: * - cookie-based
223: * - get-param-based
224: */
225: return cache_parse_lua(srv, con, p, cml_file);
226: }
227:
228: URIHANDLER_FUNC(mod_cml_power_magnet) {
229: plugin_data *p = p_d;
230:
231: mod_cml_patch_connection(srv, con, p);
232:
233: buffer_reset(p->basedir);
234: buffer_reset(p->baseurl);
235: buffer_reset(p->trigger_handler);
236:
1.1.1.3 ! misho 237: if (buffer_string_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
1.1 misho 238:
239: /*
240: * power-magnet:
241: * cml.power-magnet = server.docroot + "/rewrite.cml"
242: *
243: * is called on EACH request, take the original REQUEST_URI and modifies the
244: * request header as neccesary.
245: *
246: * First use:
247: * if file_exists("/maintainance.html") {
248: * output_include = ( "/maintainance.html" )
249: * return CACHE_HIT
250: * }
251: *
252: * as we only want to rewrite HTML like requests we should cover it in a conditional
253: *
254: * */
255:
256: switch(cache_call_lua(srv, con, p, p->conf.power_magnet)) {
257: case -1:
258: /* error */
259: if (con->conf.log_request_handling) {
260: log_error_write(srv, __FILE__, __LINE__, "s", "cache-error");
261: }
262: con->http_status = 500;
263: return HANDLER_COMEBACK;
264: case 0:
265: if (con->conf.log_request_handling) {
266: log_error_write(srv, __FILE__, __LINE__, "s", "cache-hit");
267: }
268: /* cache-hit */
269: buffer_reset(con->physical.path);
270: return HANDLER_FINISHED;
271: case 1:
272: /* cache miss */
273: return HANDLER_GO_ON;
274: default:
275: con->http_status = 500;
276: return HANDLER_COMEBACK;
277: }
278: }
279:
280: URIHANDLER_FUNC(mod_cml_is_handled) {
281: plugin_data *p = p_d;
282:
1.1.1.3 ! misho 283: if (buffer_string_is_empty(con->physical.path)) return HANDLER_ERROR;
1.1 misho 284:
285: mod_cml_patch_connection(srv, con, p);
286:
287: buffer_reset(p->basedir);
288: buffer_reset(p->baseurl);
289: buffer_reset(p->trigger_handler);
290:
1.1.1.3 ! misho 291: if (buffer_string_is_empty(p->conf.ext)) return HANDLER_GO_ON;
1.1 misho 292:
1.1.1.3 ! misho 293: if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, buffer_string_length(p->conf.ext))) {
1.1 misho 294: return HANDLER_GO_ON;
295: }
296:
297: switch(cache_call_lua(srv, con, p, con->physical.path)) {
298: case -1:
299: /* error */
300: if (con->conf.log_request_handling) {
301: log_error_write(srv, __FILE__, __LINE__, "s", "cache-error");
302: }
303: con->http_status = 500;
304: return HANDLER_COMEBACK;
305: case 0:
306: if (con->conf.log_request_handling) {
307: log_error_write(srv, __FILE__, __LINE__, "s", "cache-hit");
308: }
309: /* cache-hit */
310: buffer_reset(con->physical.path);
311: return HANDLER_FINISHED;
312: case 1:
313: if (con->conf.log_request_handling) {
314: log_error_write(srv, __FILE__, __LINE__, "s", "cache-miss");
315: }
316: /* cache miss */
317: return HANDLER_COMEBACK;
318: default:
319: con->http_status = 500;
320: return HANDLER_COMEBACK;
321: }
322: }
323:
324: int mod_cml_plugin_init(plugin *p);
325: int mod_cml_plugin_init(plugin *p) {
326: p->version = LIGHTTPD_VERSION_ID;
327: p->name = buffer_init_string("cache");
328:
329: p->init = mod_cml_init;
330: p->cleanup = mod_cml_free;
331: p->set_defaults = mod_cml_set_defaults;
332:
333: p->handle_subrequest_start = mod_cml_is_handled;
334: p->handle_physical = mod_cml_power_magnet;
335:
336: p->data = NULL;
337:
338: return 0;
339: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>