Annotation of embedaddon/lighttpd/src/mod_setenv.c, revision 1.1.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>