Annotation of embedaddon/lighttpd/src/mod_alias.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 <ctype.h>
                      8: #include <stdlib.h>
                      9: #include <string.h>
                     10: #include <stdio.h>
                     11: 
                     12: /* plugin config for all request/connections */
                     13: typedef struct {
                     14:        array *alias;
                     15: } plugin_config;
                     16: 
                     17: typedef struct {
                     18:        PLUGIN_DATA;
                     19: 
                     20:        plugin_config **config_storage;
                     21: 
                     22:        plugin_config conf;
                     23: } plugin_data;
                     24: 
                     25: /* init the plugin data */
                     26: INIT_FUNC(mod_alias_init) {
                     27:        plugin_data *p;
                     28: 
                     29:        p = calloc(1, sizeof(*p));
                     30: 
                     31: 
                     32: 
                     33:        return p;
                     34: }
                     35: 
                     36: /* detroy the plugin data */
                     37: FREE_FUNC(mod_alias_free) {
                     38:        plugin_data *p = p_d;
                     39: 
                     40:        if (!p) return HANDLER_GO_ON;
                     41: 
                     42:        if (p->config_storage) {
                     43:                size_t i;
                     44: 
                     45:                for (i = 0; i < srv->config_context->used; i++) {
                     46:                        plugin_config *s = p->config_storage[i];
                     47: 
                     48:                        if(!s) continue;
                     49: 
                     50:                        array_free(s->alias);
                     51: 
                     52:                        free(s);
                     53:                }
                     54:                free(p->config_storage);
                     55:        }
                     56: 
                     57:        free(p);
                     58: 
                     59:        return HANDLER_GO_ON;
                     60: }
                     61: 
                     62: /* handle plugin config and check values */
                     63: 
                     64: SETDEFAULTS_FUNC(mod_alias_set_defaults) {
                     65:        plugin_data *p = p_d;
                     66:        size_t i = 0;
                     67: 
                     68:        config_values_t cv[] = {
                     69:                { "alias.url",                  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
                     70:                { NULL,                         NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
                     71:        };
                     72: 
                     73:        if (!p) return HANDLER_ERROR;
                     74: 
                     75:        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
                     76: 
                     77:        for (i = 0; i < srv->config_context->used; i++) {
                     78:                plugin_config *s;
                     79: 
                     80:                s = calloc(1, sizeof(plugin_config));
                     81:                s->alias = array_init();
                     82:                cv[0].destination = s->alias;
                     83: 
                     84:                p->config_storage[i] = s;
                     85: 
                     86:                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
                     87:                        return HANDLER_ERROR;
                     88:                }
                     89:                if (s->alias->used >= 2) {
                     90:                        const array *a = s->alias;
                     91:                        size_t j, k;
                     92: 
                     93:                        for (j = 0; j < a->used; j ++) {
                     94:                                const buffer *prefix = a->data[a->sorted[j]]->key;
                     95:                                for (k = j + 1; k < a->used; k ++) {
                     96:                                        const buffer *key = a->data[a->sorted[k]]->key;
                     97: 
                     98:                                        if (key->used < prefix->used) {
                     99:                                                break;
                    100:                                        }
                    101:                                        if (memcmp(key->ptr, prefix->ptr, prefix->used - 1) != 0) {
                    102:                                                break;
                    103:                                        }
                    104:                                        /* ok, they have same prefix. check position */
                    105:                                        if (a->sorted[j] < a->sorted[k]) {
                    106:                                                log_error_write(srv, __FILE__, __LINE__, "SBSBS",
                    107:                                                        "url.alias: `", key, "' will never match as `", prefix, "' matched first");
                    108:                                                return HANDLER_ERROR;
                    109:                                        }
                    110:                                }
                    111:                        }
                    112:                }
                    113:        }
                    114: 
                    115:        return HANDLER_GO_ON;
                    116: }
                    117: 
                    118: #define PATCH(x) \
                    119:        p->conf.x = s->x;
                    120: static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) {
                    121:        size_t i, j;
                    122:        plugin_config *s = p->config_storage[0];
                    123: 
                    124:        PATCH(alias);
                    125: 
                    126:        /* skip the first, the global context */
                    127:        for (i = 1; i < srv->config_context->used; i++) {
                    128:                data_config *dc = (data_config *)srv->config_context->data[i];
                    129:                s = p->config_storage[i];
                    130: 
                    131:                /* condition didn't match */
                    132:                if (!config_check_cond(srv, con, dc)) continue;
                    133: 
                    134:                /* merge config */
                    135:                for (j = 0; j < dc->value->used; j++) {
                    136:                        data_unset *du = dc->value->data[j];
                    137: 
                    138:                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
                    139:                                PATCH(alias);
                    140:                        }
                    141:                }
                    142:        }
                    143: 
                    144:        return 0;
                    145: }
                    146: #undef PATCH
                    147: 
                    148: PHYSICALPATH_FUNC(mod_alias_physical_handler) {
                    149:        plugin_data *p = p_d;
                    150:        int uri_len, basedir_len;
                    151:        char *uri_ptr;
                    152:        size_t k;
                    153: 
                    154:        if (con->physical.path->used == 0) return HANDLER_GO_ON;
                    155: 
                    156:        mod_alias_patch_connection(srv, con, p);
                    157: 
                    158:        /* not to include the tailing slash */
                    159:        basedir_len = (con->physical.basedir->used - 1);
                    160:        if ('/' == con->physical.basedir->ptr[basedir_len-1]) --basedir_len;
                    161:        uri_len = con->physical.path->used - 1 - basedir_len;
                    162:        uri_ptr = con->physical.path->ptr + basedir_len;
                    163: 
                    164:        for (k = 0; k < p->conf.alias->used; k++) {
                    165:                data_string *ds = (data_string *)p->conf.alias->data[k];
                    166:                int alias_len = ds->key->used - 1;
                    167: 
                    168:                if (alias_len > uri_len) continue;
                    169:                if (ds->key->used == 0) continue;
                    170: 
                    171:                if (0 == (con->conf.force_lowercase_filenames ?
                    172:                                        strncasecmp(uri_ptr, ds->key->ptr, alias_len) :
                    173:                                        strncmp(uri_ptr, ds->key->ptr, alias_len))) {
                    174:                        /* matched */
                    175: 
                    176:                        buffer_copy_string_buffer(con->physical.basedir, ds->value);
                    177:                        buffer_copy_string_buffer(srv->tmp_buf, ds->value);
                    178:                        buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
                    179:                        buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
                    180: 
                    181:                        return HANDLER_GO_ON;
                    182:                }
                    183:        }
                    184: 
                    185:        /* not found */
                    186:        return HANDLER_GO_ON;
                    187: }
                    188: 
                    189: /* this function is called at dlopen() time and inits the callbacks */
                    190: 
                    191: int mod_alias_plugin_init(plugin *p);
                    192: int mod_alias_plugin_init(plugin *p) {
                    193:        p->version     = LIGHTTPD_VERSION_ID;
                    194:        p->name        = buffer_init_string("alias");
                    195: 
                    196:        p->init           = mod_alias_init;
                    197:        p->handle_physical= mod_alias_physical_handler;
                    198:        p->set_defaults   = mod_alias_set_defaults;
                    199:        p->cleanup        = mod_alias_free;
                    200: 
                    201:        p->data        = NULL;
                    202: 
                    203:        return 0;
                    204: }

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