Annotation of embedaddon/lighttpd/src/mod_cml.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>