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

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

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