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

1.1     ! misho       1: #include "base.h"
        !             2: #include "log.h"
        !             3: #include "buffer.h"
        !             4: 
        !             5: #include "plugin.h"
        !             6: 
        !             7: #include "response.h"
        !             8: 
        !             9: #include <stdlib.h>
        !            10: #include <string.h>
        !            11: 
        !            12: /* plugin config for all request/connections */
        !            13: 
        !            14: typedef struct {
        !            15:        int handled; /* make sure that we only apply the headers once */
        !            16: } handler_ctx;
        !            17: 
        !            18: typedef struct {
        !            19:        array *request_header;
        !            20:        array *response_header;
        !            21: 
        !            22:        array *environment;
        !            23: } plugin_config;
        !            24: 
        !            25: typedef struct {
        !            26:        PLUGIN_DATA;
        !            27: 
        !            28:        plugin_config **config_storage;
        !            29: 
        !            30:        plugin_config conf;
        !            31: } plugin_data;
        !            32: 
        !            33: static handler_ctx * handler_ctx_init(void) {
        !            34:        handler_ctx * hctx;
        !            35: 
        !            36:        hctx = calloc(1, sizeof(*hctx));
        !            37: 
        !            38:        hctx->handled = 0;
        !            39: 
        !            40:        return hctx;
        !            41: }
        !            42: 
        !            43: static void handler_ctx_free(handler_ctx *hctx) {
        !            44:        free(hctx);
        !            45: }
        !            46: 
        !            47: 
        !            48: /* init the plugin data */
        !            49: INIT_FUNC(mod_setenv_init) {
        !            50:        plugin_data *p;
        !            51: 
        !            52:        p = calloc(1, sizeof(*p));
        !            53: 
        !            54:        return p;
        !            55: }
        !            56: 
        !            57: /* detroy the plugin data */
        !            58: FREE_FUNC(mod_setenv_free) {
        !            59:        plugin_data *p = p_d;
        !            60: 
        !            61:        UNUSED(srv);
        !            62: 
        !            63:        if (!p) return HANDLER_GO_ON;
        !            64: 
        !            65:        if (p->config_storage) {
        !            66:                size_t i;
        !            67:                for (i = 0; i < srv->config_context->used; i++) {
        !            68:                        plugin_config *s = p->config_storage[i];
        !            69: 
        !            70:                        array_free(s->request_header);
        !            71:                        array_free(s->response_header);
        !            72:                        array_free(s->environment);
        !            73: 
        !            74:                        free(s);
        !            75:                }
        !            76:                free(p->config_storage);
        !            77:        }
        !            78: 
        !            79:        free(p);
        !            80: 
        !            81:        return HANDLER_GO_ON;
        !            82: }
        !            83: 
        !            84: /* handle plugin config and check values */
        !            85: 
        !            86: SETDEFAULTS_FUNC(mod_setenv_set_defaults) {
        !            87:        plugin_data *p = p_d;
        !            88:        size_t i = 0;
        !            89: 
        !            90:        config_values_t cv[] = {
        !            91:                { "setenv.add-request-header",  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
        !            92:                { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
        !            93:                { "setenv.add-environment",     NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
        !            94:                { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
        !            95:        };
        !            96: 
        !            97:        if (!p) return HANDLER_ERROR;
        !            98: 
        !            99:        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
        !           100: 
        !           101:        for (i = 0; i < srv->config_context->used; i++) {
        !           102:                plugin_config *s;
        !           103: 
        !           104:                s = calloc(1, sizeof(plugin_config));
        !           105:                s->request_header   = array_init();
        !           106:                s->response_header  = array_init();
        !           107:                s->environment      = array_init();
        !           108: 
        !           109:                cv[0].destination = s->request_header;
        !           110:                cv[1].destination = s->response_header;
        !           111:                cv[2].destination = s->environment;
        !           112: 
        !           113:                p->config_storage[i] = s;
        !           114: 
        !           115:                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
        !           116:                        return HANDLER_ERROR;
        !           117:                }
        !           118:        }
        !           119: 
        !           120:        return HANDLER_GO_ON;
        !           121: }
        !           122: 
        !           123: #define PATCH(x) \
        !           124:        p->conf.x = s->x;
        !           125: static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
        !           126:        size_t i, j;
        !           127:        plugin_config *s = p->config_storage[0];
        !           128: 
        !           129:        PATCH(request_header);
        !           130:        PATCH(response_header);
        !           131:        PATCH(environment);
        !           132: 
        !           133:        /* skip the first, the global context */
        !           134:        for (i = 1; i < srv->config_context->used; i++) {
        !           135:                data_config *dc = (data_config *)srv->config_context->data[i];
        !           136:                s = p->config_storage[i];
        !           137: 
        !           138:                /* condition didn't match */
        !           139:                if (!config_check_cond(srv, con, dc)) continue;
        !           140: 
        !           141:                /* merge config */
        !           142:                for (j = 0; j < dc->value->used; j++) {
        !           143:                        data_unset *du = dc->value->data[j];
        !           144: 
        !           145:                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
        !           146:                                PATCH(request_header);
        !           147:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
        !           148:                                PATCH(response_header);
        !           149:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
        !           150:                                PATCH(environment);
        !           151:                        }
        !           152:                }
        !           153:        }
        !           154: 
        !           155:        return 0;
        !           156: }
        !           157: #undef PATCH
        !           158: 
        !           159: URIHANDLER_FUNC(mod_setenv_uri_handler) {
        !           160:        plugin_data *p = p_d;
        !           161:        size_t k;
        !           162:        handler_ctx *hctx;
        !           163: 
        !           164:        if (con->plugin_ctx[p->id]) {
        !           165:                hctx = con->plugin_ctx[p->id];
        !           166:        } else {
        !           167:                hctx = handler_ctx_init();
        !           168: 
        !           169:                con->plugin_ctx[p->id] = hctx;
        !           170:        }
        !           171: 
        !           172:        if (hctx->handled) {
        !           173:                return HANDLER_GO_ON;
        !           174:        }
        !           175: 
        !           176:        hctx->handled = 1;
        !           177: 
        !           178:        mod_setenv_patch_connection(srv, con, p);
        !           179: 
        !           180:        for (k = 0; k < p->conf.request_header->used; k++) {
        !           181:                data_string *ds = (data_string *)p->conf.request_header->data[k];
        !           182:                data_string *ds_dst;
        !           183: 
        !           184:                if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
        !           185:                        ds_dst = data_string_init();
        !           186:                }
        !           187: 
        !           188:                buffer_copy_string_buffer(ds_dst->key, ds->key);
        !           189:                buffer_copy_string_buffer(ds_dst->value, ds->value);
        !           190: 
        !           191:                array_insert_unique(con->request.headers, (data_unset *)ds_dst);
        !           192:        }
        !           193: 
        !           194:        for (k = 0; k < p->conf.environment->used; k++) {
        !           195:                data_string *ds = (data_string *)p->conf.environment->data[k];
        !           196:                data_string *ds_dst;
        !           197: 
        !           198:                if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
        !           199:                        ds_dst = data_string_init();
        !           200:                }
        !           201: 
        !           202:                buffer_copy_string_buffer(ds_dst->key, ds->key);
        !           203:                buffer_copy_string_buffer(ds_dst->value, ds->value);
        !           204: 
        !           205:                array_insert_unique(con->environment, (data_unset *)ds_dst);
        !           206:        }
        !           207: 
        !           208:        for (k = 0; k < p->conf.response_header->used; k++) {
        !           209:                data_string *ds = (data_string *)p->conf.response_header->data[k];
        !           210: 
        !           211:                response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
        !           212:        }
        !           213: 
        !           214:        /* not found */
        !           215:        return HANDLER_GO_ON;
        !           216: }
        !           217: 
        !           218: CONNECTION_FUNC(mod_setenv_reset) {
        !           219:        plugin_data *p = p_d;
        !           220: 
        !           221:        UNUSED(srv);
        !           222: 
        !           223:        if (con->plugin_ctx[p->id]) {
        !           224:                handler_ctx_free(con->plugin_ctx[p->id]);
        !           225:                con->plugin_ctx[p->id] = NULL;
        !           226:        }
        !           227: 
        !           228:        return HANDLER_GO_ON;
        !           229: }
        !           230: 
        !           231: /* this function is called at dlopen() time and inits the callbacks */
        !           232: 
        !           233: int mod_setenv_plugin_init(plugin *p);
        !           234: int mod_setenv_plugin_init(plugin *p) {
        !           235:        p->version     = LIGHTTPD_VERSION_ID;
        !           236:        p->name        = buffer_init_string("setenv");
        !           237: 
        !           238:        p->init        = mod_setenv_init;
        !           239:        p->handle_uri_clean  = mod_setenv_uri_handler;
        !           240:        p->set_defaults  = mod_setenv_set_defaults;
        !           241:        p->cleanup     = mod_setenv_free;
        !           242: 
        !           243:        p->connection_reset  = mod_setenv_reset;
        !           244: 
        !           245:        p->data        = NULL;
        !           246: 
        !           247:        return 0;
        !           248: }

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