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

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