Annotation of embedaddon/lighttpd/src/mod_alias.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 <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>