Annotation of embedaddon/lighttpd/src/mod_staticfile.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 "stat_cache.h"
                     10: #include "etag.h"
                     11: #include "http_chunk.h"
                     12: #include "response.h"
                     13: 
                     14: #include <ctype.h>
                     15: #include <stdlib.h>
                     16: #include <stdio.h>
                     17: #include <string.h>
                     18: 
                     19: /**
                     20:  * this is a staticfile for a lighttpd plugin
                     21:  *
                     22:  */
                     23: 
                     24: 
                     25: 
                     26: /* plugin config for all request/connections */
                     27: 
                     28: typedef struct {
                     29:        array *exclude_ext;
                     30:        unsigned short etags_used;
                     31:        unsigned short disable_pathinfo;
                     32: } plugin_config;
                     33: 
                     34: typedef struct {
                     35:        PLUGIN_DATA;
                     36: 
                     37:        plugin_config **config_storage;
                     38: 
                     39:        plugin_config conf;
                     40: } plugin_data;
                     41: 
                     42: /* init the plugin data */
                     43: INIT_FUNC(mod_staticfile_init) {
                     44:        plugin_data *p;
                     45: 
                     46:        p = calloc(1, sizeof(*p));
                     47: 
                     48:        return p;
                     49: }
                     50: 
                     51: /* detroy the plugin data */
                     52: FREE_FUNC(mod_staticfile_free) {
                     53:        plugin_data *p = p_d;
                     54: 
                     55:        UNUSED(srv);
                     56: 
                     57:        if (!p) return HANDLER_GO_ON;
                     58: 
                     59:        if (p->config_storage) {
                     60:                size_t i;
                     61:                for (i = 0; i < srv->config_context->used; i++) {
                     62:                        plugin_config *s = p->config_storage[i];
                     63: 
1.1.1.3 ! misho      64:                        if (NULL == s) continue;
        !            65: 
1.1       misho      66:                        array_free(s->exclude_ext);
                     67: 
                     68:                        free(s);
                     69:                }
                     70:                free(p->config_storage);
                     71:        }
                     72: 
                     73:        free(p);
                     74: 
                     75:        return HANDLER_GO_ON;
                     76: }
                     77: 
                     78: /* handle plugin config and check values */
                     79: 
                     80: SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
                     81:        plugin_data *p = p_d;
                     82:        size_t i = 0;
                     83: 
                     84:        config_values_t cv[] = {
                     85:                { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
                     86:                { "static-file.etags",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
                     87:                { "static-file.disable-pathinfo", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
                     88:                { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
                     89:        };
                     90: 
                     91:        if (!p) return HANDLER_ERROR;
                     92: 
1.1.1.2   misho      93:        p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
1.1       misho      94: 
                     95:        for (i = 0; i < srv->config_context->used; i++) {
1.1.1.3 ! misho      96:                data_config const* config = (data_config const*)srv->config_context->data[i];
1.1       misho      97:                plugin_config *s;
                     98: 
                     99:                s = calloc(1, sizeof(plugin_config));
                    100:                s->exclude_ext    = array_init();
                    101:                s->etags_used     = 1;
                    102:                s->disable_pathinfo = 0;
                    103: 
                    104:                cv[0].destination = s->exclude_ext;
                    105:                cv[1].destination = &(s->etags_used);
                    106:                cv[2].destination = &(s->disable_pathinfo);
                    107: 
                    108:                p->config_storage[i] = s;
                    109: 
1.1.1.3 ! misho     110:                if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
1.1       misho     111:                        return HANDLER_ERROR;
                    112:                }
                    113:        }
                    114: 
                    115:        return HANDLER_GO_ON;
                    116: }
                    117: 
                    118: #define PATCH(x) \
                    119:        p->conf.x = s->x;
                    120: static int mod_staticfile_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(exclude_ext);
                    125:        PATCH(etags_used);
                    126:        PATCH(disable_pathinfo);
                    127: 
                    128:        /* skip the first, the global context */
                    129:        for (i = 1; i < srv->config_context->used; i++) {
                    130:                data_config *dc = (data_config *)srv->config_context->data[i];
                    131:                s = p->config_storage[i];
                    132: 
                    133:                /* condition didn't match */
                    134:                if (!config_check_cond(srv, con, dc)) continue;
                    135: 
                    136:                /* merge config */
                    137:                for (j = 0; j < dc->value->used; j++) {
                    138:                        data_unset *du = dc->value->data[j];
                    139: 
                    140:                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
                    141:                                PATCH(exclude_ext);
                    142:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.etags"))) {
                    143:                                PATCH(etags_used);
                    144:                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.disable-pathinfo"))) {
                    145:                                PATCH(disable_pathinfo);
                    146:                        }
                    147:                }
                    148:        }
                    149: 
                    150:        return 0;
                    151: }
                    152: #undef PATCH
                    153: 
                    154: URIHANDLER_FUNC(mod_staticfile_subrequest) {
                    155:        plugin_data *p = p_d;
                    156:        size_t k;
                    157:        data_string *ds;
                    158: 
                    159:        /* someone else has done a decision for us */
                    160:        if (con->http_status != 0) return HANDLER_GO_ON;
1.1.1.3 ! misho     161:        if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
        !           162:        if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
1.1       misho     163: 
                    164:        /* someone else has handled this request */
                    165:        if (con->mode != DIRECT) return HANDLER_GO_ON;
                    166: 
                    167:        /* we only handle GET, POST and HEAD */
                    168:        switch(con->request.http_method) {
                    169:        case HTTP_METHOD_GET:
                    170:        case HTTP_METHOD_POST:
                    171:        case HTTP_METHOD_HEAD:
                    172:                break;
                    173:        default:
                    174:                return HANDLER_GO_ON;
                    175:        }
                    176: 
                    177:        mod_staticfile_patch_connection(srv, con, p);
                    178: 
1.1.1.3 ! misho     179:        if (p->conf.disable_pathinfo && !buffer_string_is_empty(con->request.pathinfo)) {
1.1       misho     180:                if (con->conf.log_request_handling) {
                    181:                        log_error_write(srv, __FILE__, __LINE__,  "s",  "-- NOT handling file as static file, pathinfo forbidden");
                    182:                }
                    183:                return HANDLER_GO_ON;
                    184:        }
                    185: 
                    186:        /* ignore certain extensions */
                    187:        for (k = 0; k < p->conf.exclude_ext->used; k++) {
                    188:                ds = (data_string *)p->conf.exclude_ext->data[k];
                    189: 
1.1.1.3 ! misho     190:                if (buffer_is_empty(ds->value)) continue;
1.1       misho     191: 
1.1.1.3 ! misho     192:                if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) {
1.1       misho     193:                        if (con->conf.log_request_handling) {
                    194:                                log_error_write(srv, __FILE__, __LINE__,  "s",  "-- NOT handling file as static file, extension forbidden");
                    195:                        }
                    196:                        return HANDLER_GO_ON;
                    197:                }
                    198:        }
                    199: 
                    200: 
                    201:        if (con->conf.log_request_handling) {
                    202:                log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling file as static file");
                    203:        }
                    204: 
1.1.1.3 ! misho     205:        if (!p->conf.etags_used) con->etag_flags = 0;
        !           206:        http_response_send_file(srv, con, con->physical.path);
1.1       misho     207: 
                    208:        return HANDLER_FINISHED;
                    209: }
                    210: 
                    211: /* this function is called at dlopen() time and inits the callbacks */
                    212: 
                    213: int mod_staticfile_plugin_init(plugin *p);
                    214: int mod_staticfile_plugin_init(plugin *p) {
                    215:        p->version     = LIGHTTPD_VERSION_ID;
                    216:        p->name        = buffer_init_string("staticfile");
                    217: 
                    218:        p->init        = mod_staticfile_init;
                    219:        p->handle_subrequest_start = mod_staticfile_subrequest;
                    220:        p->set_defaults  = mod_staticfile_set_defaults;
                    221:        p->cleanup     = mod_staticfile_free;
                    222: 
                    223:        p->data        = NULL;
                    224: 
                    225:        return 0;
                    226: }

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