File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / mod_indexfile.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (7 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

    1: #include "first.h"
    2: 
    3: #include "base.h"
    4: #include "log.h"
    5: #include "buffer.h"
    6: 
    7: #include "plugin.h"
    8: 
    9: #include "stat_cache.h"
   10: 
   11: #include <ctype.h>
   12: #include <stdlib.h>
   13: #include <string.h>
   14: #include <errno.h>
   15: 
   16: /* plugin config for all request/connections */
   17: 
   18: typedef struct {
   19: 	array *indexfiles;
   20: } plugin_config;
   21: 
   22: typedef struct {
   23: 	PLUGIN_DATA;
   24: 
   25: 	buffer *tmp_buf;
   26: 
   27: 	plugin_config **config_storage;
   28: 
   29: 	plugin_config conf;
   30: } plugin_data;
   31: 
   32: /* init the plugin data */
   33: INIT_FUNC(mod_indexfile_init) {
   34: 	plugin_data *p;
   35: 
   36: 	p = calloc(1, sizeof(*p));
   37: 
   38: 	p->tmp_buf = buffer_init();
   39: 
   40: 	return p;
   41: }
   42: 
   43: /* detroy the plugin data */
   44: FREE_FUNC(mod_indexfile_free) {
   45: 	plugin_data *p = p_d;
   46: 
   47: 	UNUSED(srv);
   48: 
   49: 	if (!p) return HANDLER_GO_ON;
   50: 
   51: 	if (p->config_storage) {
   52: 		size_t i;
   53: 		for (i = 0; i < srv->config_context->used; i++) {
   54: 			plugin_config *s = p->config_storage[i];
   55: 
   56: 			if (NULL == s) continue;
   57: 
   58: 			array_free(s->indexfiles);
   59: 
   60: 			free(s);
   61: 		}
   62: 		free(p->config_storage);
   63: 	}
   64: 
   65: 	buffer_free(p->tmp_buf);
   66: 
   67: 	free(p);
   68: 
   69: 	return HANDLER_GO_ON;
   70: }
   71: 
   72: /* handle plugin config and check values */
   73: 
   74: SETDEFAULTS_FUNC(mod_indexfile_set_defaults) {
   75: 	plugin_data *p = p_d;
   76: 	size_t i = 0;
   77: 
   78: 	config_values_t cv[] = {
   79: 		{ "index-file.names",           NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
   80: 		{ "server.indexfiles",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
   81: 		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
   82: 	};
   83: 
   84: 	if (!p) return HANDLER_ERROR;
   85: 
   86: 	p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
   87: 
   88: 	for (i = 0; i < srv->config_context->used; i++) {
   89: 		data_config const* config = (data_config const*)srv->config_context->data[i];
   90: 		plugin_config *s;
   91: 
   92: 		s = calloc(1, sizeof(plugin_config));
   93: 		s->indexfiles    = array_init();
   94: 
   95: 		cv[0].destination = s->indexfiles;
   96: 		cv[1].destination = s->indexfiles; /* old name for [0] */
   97: 
   98: 		p->config_storage[i] = s;
   99: 
  100: 		if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
  101: 			return HANDLER_ERROR;
  102: 		}
  103: 	}
  104: 
  105: 	return HANDLER_GO_ON;
  106: }
  107: 
  108: #define PATCH(x) \
  109: 	p->conf.x = s->x;
  110: static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
  111: 	size_t i, j;
  112: 	plugin_config *s = p->config_storage[0];
  113: 
  114: 	PATCH(indexfiles);
  115: 
  116: 	/* skip the first, the global context */
  117: 	for (i = 1; i < srv->config_context->used; i++) {
  118: 		data_config *dc = (data_config *)srv->config_context->data[i];
  119: 		s = p->config_storage[i];
  120: 
  121: 		/* condition didn't match */
  122: 		if (!config_check_cond(srv, con, dc)) continue;
  123: 
  124: 		/* merge config */
  125: 		for (j = 0; j < dc->value->used; j++) {
  126: 			data_unset *du = dc->value->data[j];
  127: 
  128: 			if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) {
  129: 				PATCH(indexfiles);
  130: 			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
  131: 				PATCH(indexfiles);
  132: 			}
  133: 		}
  134: 	}
  135: 
  136: 	return 0;
  137: }
  138: #undef PATCH
  139: 
  140: URIHANDLER_FUNC(mod_indexfile_subrequest) {
  141: 	plugin_data *p = p_d;
  142: 	size_t k;
  143: 	stat_cache_entry *sce = NULL;
  144: 
  145: 	if (con->mode != DIRECT) return HANDLER_GO_ON;
  146: 
  147: 	if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
  148: 	if (con->uri.path->ptr[buffer_string_length(con->uri.path) - 1] != '/') return HANDLER_GO_ON;
  149: 
  150: 	mod_indexfile_patch_connection(srv, con, p);
  151: 
  152: 	if (con->conf.log_request_handling) {
  153: 		log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Indexfile");
  154: 		log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
  155: 	}
  156: 
  157: 	/* indexfile */
  158: 	for (k = 0; k < p->conf.indexfiles->used; k++) {
  159: 		data_string *ds = (data_string *)p->conf.indexfiles->data[k];
  160: 
  161: 		if (ds->value && ds->value->ptr[0] == '/') {
  162: 			/* if the index-file starts with a prefix as use this file as
  163: 			 * index-generator */
  164: 			buffer_copy_buffer(p->tmp_buf, con->physical.doc_root);
  165: 		} else {
  166: 			buffer_copy_buffer(p->tmp_buf, con->physical.path);
  167: 		}
  168: 		buffer_append_string_buffer(p->tmp_buf, ds->value);
  169: 
  170: 		if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
  171: 			if (errno == EACCES) {
  172: 				con->http_status = 403;
  173: 				buffer_reset(con->physical.path);
  174: 
  175: 				return HANDLER_FINISHED;
  176: 			}
  177: 
  178: 			if (errno != ENOENT &&
  179: 			    errno != ENOTDIR) {
  180: 				/* we have no idea what happend. let's tell the user so. */
  181: 
  182: 				con->http_status = 500;
  183: 
  184: 				log_error_write(srv, __FILE__, __LINE__, "ssbsb",
  185: 						"file not found ... or so: ", strerror(errno),
  186: 						con->uri.path,
  187: 						"->", con->physical.path);
  188: 
  189: 				buffer_reset(con->physical.path);
  190: 
  191: 				return HANDLER_FINISHED;
  192: 			}
  193: 			continue;
  194: 		}
  195: 
  196: 		if (ds->value && ds->value->ptr[0] == '/') {
  197: 			/* replace uri.path */
  198: 			buffer_copy_buffer(con->uri.path, ds->value);
  199: 
  200: 			if (NULL == (ds = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
  201: 				ds = data_string_init();
  202: 			}
  203: 			buffer_copy_string_len(ds->key, CONST_STR_LEN("PATH_TRANSLATED_DIRINDEX"));
  204: 			buffer_copy_buffer(ds->value, con->physical.path);
  205: 			array_insert_unique(con->environment, (data_unset *)ds);
  206: 		} else {
  207: 			/* append to uri.path the relative path to index file (/ -> /index.php) */
  208: 			buffer_append_string_buffer(con->uri.path, ds->value);
  209: 		}
  210: 
  211: 		buffer_copy_buffer(con->physical.path, p->tmp_buf);
  212: 
  213: 		return HANDLER_GO_ON;
  214: 	}
  215: 
  216: 	/* not found */
  217: 	return HANDLER_GO_ON;
  218: }
  219: 
  220: /* this function is called at dlopen() time and inits the callbacks */
  221: 
  222: int mod_indexfile_plugin_init(plugin *p);
  223: int mod_indexfile_plugin_init(plugin *p) {
  224: 	p->version     = LIGHTTPD_VERSION_ID;
  225: 	p->name        = buffer_init_string("indexfile");
  226: 
  227: 	p->init        = mod_indexfile_init;
  228: 	p->handle_subrequest_start = mod_indexfile_subrequest;
  229: 	p->set_defaults  = mod_indexfile_set_defaults;
  230: 	p->cleanup     = mod_indexfile_free;
  231: 
  232: 	p->data        = NULL;
  233: 
  234: 	return 0;
  235: }

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