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