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>