Annotation of embedaddon/lighttpd/src/mod_simple_vhost.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: #include "stat_cache.h"
                      7: 
                      8: #include "plugin.h"
                      9: 
                     10: #include <assert.h>
                     11: #include <ctype.h>
                     12: #include <stdlib.h>
                     13: #include <string.h>
                     14: #include <errno.h>
                     15: 
                     16: typedef struct {
                     17:        buffer *server_root;
                     18:        buffer *default_host;
                     19:        buffer *document_root;
                     20: 
                     21:        buffer *docroot_cache_key;
                     22:        buffer *docroot_cache_value;
                     23:        buffer *docroot_cache_servername;
                     24: 
                     25:        unsigned short debug;
                     26: } plugin_config;
                     27: 
                     28: typedef struct {
                     29:        PLUGIN_DATA;
                     30: 
                     31:        buffer *doc_root;
                     32: 
                     33:        plugin_config **config_storage;
                     34:        plugin_config conf;
                     35: } plugin_data;
                     36: 
                     37: INIT_FUNC(mod_simple_vhost_init) {
                     38:        plugin_data *p;
                     39: 
                     40:        p = calloc(1, sizeof(*p));
                     41: 
                     42:        p->doc_root = buffer_init();
                     43: 
                     44:        return p;
                     45: }
                     46: 
                     47: FREE_FUNC(mod_simple_vhost_free) {
                     48:        plugin_data *p = p_d;
                     49: 
                     50:        UNUSED(srv);
                     51: 
                     52:        if (!p) return HANDLER_GO_ON;
                     53: 
                     54:        if (p->config_storage) {
                     55:                size_t i;
                     56:                for (i = 0; i < srv->config_context->used; i++) {
                     57:                        plugin_config *s = p->config_storage[i];
                     58: 
                     59:                        buffer_free(s->document_root);
                     60:                        buffer_free(s->default_host);
                     61:                        buffer_free(s->server_root);
                     62: 
                     63:                        buffer_free(s->docroot_cache_key);
                     64:                        buffer_free(s->docroot_cache_value);
                     65:                        buffer_free(s->docroot_cache_servername);
                     66: 
                     67:                        free(s);
                     68:                }
                     69: 
                     70:                free(p->config_storage);
                     71:        }
                     72: 
                     73:        buffer_free(p->doc_root);
                     74: 
                     75:        free(p);
                     76: 
                     77:        return HANDLER_GO_ON;
                     78: }
                     79: 
                     80: SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) {
                     81:        plugin_data *p = p_d;
                     82:        size_t i;
                     83: 
                     84:        config_values_t cv[] = {
                     85:                { "simple-vhost.server-root",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
                     86:                { "simple-vhost.default-host",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
                     87:                { "simple-vhost.document-root",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
                     88:                { "simple-vhost.debug",             NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
                     89:                { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
                     90:        };
                     91: 
                     92:        if (!p) return HANDLER_ERROR;
                     93: 
1.1.1.2   misho      94:        p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
1.1       misho      95: 
                     96:        for (i = 0; i < srv->config_context->used; i++) {
1.1.1.3 ! misho      97:                data_config const* config = (data_config const*)srv->config_context->data[i];
1.1       misho      98:                plugin_config *s;
                     99: 
                    100:                s = calloc(1, sizeof(plugin_config));
                    101: 
                    102:                s->server_root = buffer_init();
                    103:                s->default_host = buffer_init();
                    104:                s->document_root = buffer_init();
                    105: 
                    106:                s->docroot_cache_key = buffer_init();
                    107:                s->docroot_cache_value = buffer_init();
                    108:                s->docroot_cache_servername = buffer_init();
                    109: 
                    110:                s->debug = 0;
                    111: 
                    112:                cv[0].destination = s->server_root;
                    113:                cv[1].destination = s->default_host;
                    114:                cv[2].destination = s->document_root;
                    115:                cv[3].destination = &(s->debug);
                    116: 
                    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: static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) {
                    129:        stat_cache_entry *sce = NULL;
1.1.1.3 ! misho     130:        force_assert(!buffer_string_is_empty(p->conf.server_root));
1.1       misho     131: 
1.1.1.3 ! misho     132:        buffer_string_prepare_copy(out, 127);
        !           133:        buffer_copy_buffer(out, p->conf.server_root);
1.1       misho     134: 
1.1.1.3 ! misho     135:        if (!buffer_string_is_empty(host)) {
1.1       misho     136:                /* a hostname has to start with a alpha-numerical character
                    137:                 * and must not contain a slash "/"
                    138:                 */
                    139:                char *dp;
                    140: 
1.1.1.3 ! misho     141:                buffer_append_slash(out);
1.1       misho     142: 
                    143:                if (NULL == (dp = strchr(host->ptr, ':'))) {
                    144:                        buffer_append_string_buffer(out, host);
                    145:                } else {
                    146:                        buffer_append_string_len(out, host->ptr, dp - host->ptr);
                    147:                }
                    148:        }
1.1.1.3 ! misho     149:        buffer_append_slash(out);
1.1       misho     150: 
1.1.1.3 ! misho     151:        if (buffer_string_length(p->conf.document_root) > 1 && p->conf.document_root->ptr[0] == '/') {
        !           152:                buffer_append_string_len(out, p->conf.document_root->ptr + 1, buffer_string_length(p->conf.document_root) - 1);
1.1       misho     153:        } else {
                    154:                buffer_append_string_buffer(out, p->conf.document_root);
1.1.1.3 ! misho     155:                buffer_append_slash(out);
1.1       misho     156:        }
                    157: 
                    158:        if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
                    159:                if (p->conf.debug) {
                    160:                        log_error_write(srv, __FILE__, __LINE__, "sb",
                    161:                                        strerror(errno), out);
                    162:                }
                    163:                return -1;
                    164:        } else if (!S_ISDIR(sce->st.st_mode)) {
                    165:                return -1;
                    166:        }
                    167: 
                    168:        return 0;
                    169: }
                    170: 
                    171: 
                    172: #define PATCH(x) \
                    173:        p->conf.x = s->x;
                    174: static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
                    175:        size_t i, j;
                    176:        plugin_config *s = p->config_storage[0];
                    177: 
                    178:        PATCH(server_root);
                    179:        PATCH(default_host);
                    180:        PATCH(document_root);
                    181: 
                    182:        PATCH(docroot_cache_key);
                    183:        PATCH(docroot_cache_value);
                    184:        PATCH(docroot_cache_servername);
                    185: 
                    186:        PATCH(debug);
                    187: 
                    188:        /* skip the first, the global context */
                    189:        for (i = 1; i < srv->config_context->used; i++) {
                    190:                data_config *dc = (data_config *)srv->config_context->data[i];
                    191:                s = p->config_storage[i];
                    192: 
                    193:                /* condition didn't match */
                    194:                if (!config_check_cond(srv, con, dc)) continue;
                    195: 
                    196:                /* merge config */
                    197:                for (j = 0; j < dc->value->used; j++) {
                    198:                        data_unset *du = dc->value->data[j];
                    199: 
                    200:                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) {
                    201:                                PATCH(server_root);
                    202:                                PATCH(docroot_cache_key);
                    203:                                PATCH(docroot_cache_value);
                    204:                                PATCH(docroot_cache_servername);
                    205:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) {
                    206:                                PATCH(default_host);
                    207:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) {
                    208:                                PATCH(document_root);
                    209:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) {
                    210:                                PATCH(debug);
                    211:                        }
                    212:                }
                    213:        }
                    214: 
                    215:        return 0;
                    216: }
                    217: #undef PATCH
                    218: 
                    219: static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
                    220:        plugin_data *p = p_data;
                    221: 
                    222:        /*
                    223:         * cache the last successfull translation from hostname (authority) to docroot
                    224:         * - this saves us a stat() call
                    225:         *
                    226:         */
                    227: 
                    228:        mod_simple_vhost_patch_connection(srv, con, p);
                    229: 
                    230:        /* build_doc_root() requires a server_root; skip module if simple-vhost.server-root is not set
                    231:         * or set to an empty string (especially don't cache any results!)
                    232:         */
1.1.1.3 ! misho     233:        if (buffer_string_is_empty(p->conf.server_root)) return HANDLER_GO_ON;
1.1       misho     234: 
1.1.1.3 ! misho     235:        if (!buffer_string_is_empty(p->conf.docroot_cache_key) &&
        !           236:            !buffer_string_is_empty(con->uri.authority) &&
1.1       misho     237:            buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
                    238:                /* cache hit */
1.1.1.3 ! misho     239:                buffer_copy_buffer(con->server_name,       p->conf.docroot_cache_servername);
        !           240:                buffer_copy_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
1.1       misho     241:        } else {
                    242:                /* build document-root */
1.1.1.3 ! misho     243:                if (buffer_string_is_empty(con->uri.authority) ||
1.1       misho     244:                    build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) {
                    245:                        /* not found, fallback the default-host */
                    246:                        if (0 == build_doc_root(srv, con, p,
                    247:                                           p->doc_root,
                    248:                                           p->conf.default_host)) {
                    249:                                /* default host worked */
1.1.1.3 ! misho     250:                                buffer_copy_buffer(con->server_name, p->conf.default_host);
        !           251:                                buffer_copy_buffer(con->physical.doc_root, p->doc_root);
1.1       misho     252:                                /* do not cache default host */
                    253:                        }
                    254:                        return HANDLER_GO_ON;
                    255:                }
                    256: 
                    257:                /* found host */
1.1.1.3 ! misho     258:                buffer_copy_buffer(con->server_name, con->uri.authority);
        !           259:                buffer_copy_buffer(con->physical.doc_root, p->doc_root);
1.1       misho     260: 
                    261:                /* copy to cache */
1.1.1.3 ! misho     262:                buffer_copy_buffer(p->conf.docroot_cache_key,        con->uri.authority);
        !           263:                buffer_copy_buffer(p->conf.docroot_cache_value,      p->doc_root);
        !           264:                buffer_copy_buffer(p->conf.docroot_cache_servername, con->server_name);
1.1       misho     265:        }
                    266: 
                    267:        return HANDLER_GO_ON;
                    268: }
                    269: 
                    270: 
                    271: int mod_simple_vhost_plugin_init(plugin *p);
                    272: int mod_simple_vhost_plugin_init(plugin *p) {
                    273:        p->version     = LIGHTTPD_VERSION_ID;
                    274:        p->name        = buffer_init_string("simple_vhost");
                    275: 
                    276:        p->init        = mod_simple_vhost_init;
                    277:        p->set_defaults = mod_simple_vhost_set_defaults;
                    278:        p->handle_docroot  = mod_simple_vhost_docroot;
                    279:        p->cleanup     = mod_simple_vhost_free;
                    280: 
                    281:        p->data        = NULL;
                    282: 
                    283:        return 0;
                    284: }

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