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>