Mercurial > hg > nginx
comparison src/http/modules/ngx_http_index_handler.c @ 96:a23d010f356d
nginx-0.0.1-2003-05-27-16:18:54 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 27 May 2003 12:18:54 +0000 |
parents | 637625a2acdb |
children | 70d2345a903f |
comparison
equal
deleted
inserted
replaced
95:b48066122884 | 96:a23d010f356d |
---|---|
1 | 1 |
2 #include <ngx_config.h> | |
3 | |
4 #include <ngx_core.h> | |
5 #include <ngx_errno.h> | |
6 #include <ngx_string.h> | |
7 #include <ngx_files.h> | |
8 #include <ngx_conf_file.h> | |
9 | |
10 #include <ngx_http.h> | |
11 #include <ngx_http_config.h> | |
12 #include <ngx_http_core_module.h> | |
13 #include <ngx_http_index_handler.h> | 2 #include <ngx_http_index_handler.h> |
14 | 3 |
15 | 4 |
16 static int ngx_http_index_test_dir(ngx_http_request_t *r); | 5 static int ngx_http_index_test_dir(ngx_http_request_t *r); |
17 static int ngx_http_index_init(ngx_pool_t *pool); | 6 static int ngx_http_index_init(ngx_pool_t *pool); |
18 static void *ngx_http_index_create_conf(ngx_pool_t *pool); | 7 static void *ngx_http_index_create_conf(ngx_pool_t *pool); |
19 static char *ngx_http_index_merge_conf(ngx_pool_t *p, | 8 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, |
20 void *parent, void *child); | 9 void *child); |
21 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, | 10 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, |
22 char *conf); | 11 void *conf); |
23 | 12 |
24 | 13 |
25 static ngx_command_t ngx_http_index_commands[] = { | 14 static ngx_command_t ngx_http_index_commands[] = { |
26 | 15 |
27 {ngx_string("index"), | 16 {ngx_string("index"), |
29 ngx_http_index_set_index, | 18 ngx_http_index_set_index, |
30 NGX_HTTP_LOC_CONF_OFFSET, | 19 NGX_HTTP_LOC_CONF_OFFSET, |
31 0, | 20 0, |
32 NULL}, | 21 NULL}, |
33 | 22 |
34 {ngx_string(""), 0, NULL, 0, 0, NULL} | 23 ngx_null_command |
35 }; | 24 }; |
36 | 25 |
37 | 26 |
38 ngx_http_module_t ngx_http_index_module_ctx = { | 27 ngx_http_module_t ngx_http_index_module_ctx = { |
39 NGX_HTTP_MODULE, | |
40 | |
41 NULL, /* create main configuration */ | 28 NULL, /* create main configuration */ |
42 NULL, /* init main configuration */ | 29 NULL, /* init main configuration */ |
43 | 30 |
44 NULL, /* create server configuration */ | 31 NULL, /* create server configuration */ |
45 NULL, /* merge server configuration */ | 32 NULL, /* merge server configuration */ |
48 ngx_http_index_merge_conf /* merge location configration */ | 35 ngx_http_index_merge_conf /* merge location configration */ |
49 }; | 36 }; |
50 | 37 |
51 | 38 |
52 ngx_module_t ngx_http_index_module = { | 39 ngx_module_t ngx_http_index_module = { |
40 NGX_MODULE, | |
53 &ngx_http_index_module_ctx, /* module context */ | 41 &ngx_http_index_module_ctx, /* module context */ |
54 0, /* module index */ | |
55 ngx_http_index_commands, /* module directives */ | 42 ngx_http_index_commands, /* module directives */ |
56 NGX_HTTP_MODULE_TYPE, /* module type */ | 43 NGX_HTTP_MODULE, /* module type */ |
57 ngx_http_index_init /* init module */ | 44 ngx_http_index_init /* init module */ |
58 }; | 45 }; |
59 | 46 |
60 | 47 |
61 /* | 48 /* |
62 Try to open first index file before the test of the directory existence | 49 Try to open first index file before the test of the directory existence |
63 because the valid requests should be many more then invalid ones. | 50 because the valid requests should be many more then invalid ones. |
64 If open() failed then stat() should be more quickly because some data | 51 If open() failed then stat() should be more quickly because some data |
65 is already cached in the kernel. | 52 is already cached in the kernel. |
66 Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) and | 53 Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR). |
67 Unix has ENOTDIR error (although it less helpfull). | 54 Unix has ENOTDIR error, although it less helpfull - it shows only |
55 that path contains the usual file in place of the directory. | |
68 */ | 56 */ |
69 | 57 |
70 int ngx_http_index_handler(ngx_http_request_t *r) | 58 int ngx_http_index_handler(ngx_http_request_t *r) |
71 { | 59 { |
72 int i, rc, test_dir; | 60 int i, rc, test_dir; |
73 char *name, *file; | 61 char *name, *file; |
74 ngx_str_t loc, *index; | 62 ngx_str_t loc, *index; |
75 ngx_err_t err; | 63 ngx_err_t err; |
76 ngx_fd_t fd; | 64 ngx_fd_t fd; |
77 | 65 ngx_http_index_conf_t *icf; |
78 ngx_http_index_conf_t *cf; | 66 ngx_http_core_loc_conf_t *clcf; |
79 ngx_http_core_loc_conf_t *core_cf; | 67 |
80 | 68 icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); |
81 cf = (ngx_http_index_conf_t *) | 69 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
82 ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx); | |
83 | |
84 core_cf = (ngx_http_core_loc_conf_t *) | |
85 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); | |
86 | 70 |
87 ngx_test_null(r->path.data, | 71 ngx_test_null(r->path.data, |
88 ngx_palloc(r->pool, | 72 ngx_palloc(r->pool, |
89 core_cf->doc_root.len + r->uri.len | 73 clcf->doc_root.len + r->uri.len |
90 + cf->max_index_len), | 74 + icf->max_index_len), |
91 NGX_HTTP_INTERNAL_SERVER_ERROR); | 75 NGX_HTTP_INTERNAL_SERVER_ERROR); |
92 | 76 |
93 loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, | 77 loc.data = ngx_cpystrn(r->path.data, clcf->doc_root.data, |
94 core_cf->doc_root.len + 1); | 78 clcf->doc_root.len + 1); |
95 file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); | 79 file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); |
96 r->path.len = file - r->path.data; | 80 r->path.len = file - r->path.data; |
97 | 81 |
98 test_dir = 1; | 82 test_dir = 1; |
99 | 83 |
100 index = (ngx_str_t *) cf->indices->elts; | 84 index = (ngx_str_t *) icf->indices.elts; |
101 for (i = 0; i < cf->indices->nelts; i++) { | 85 for (i = 0; i < icf->indices.nelts; i++) { |
102 | 86 |
103 if (index[i].data[0] != '/') { | 87 if (index[i].data[0] != '/') { |
104 ngx_memcpy(file, index[i].data, index[i].len + 1); | 88 ngx_memcpy(file, index[i].data, index[i].len + 1); |
105 name = r->path.data; | 89 name = r->path.data; |
106 | 90 |
145 ngx_open_file_n " %s failed", name); | 129 ngx_open_file_n " %s failed", name); |
146 | 130 |
147 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 131 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
148 } | 132 } |
149 | 133 |
150 r->file.name.data = name; | 134 r->file.name.data = name; |
151 r->file.fd = fd; | 135 r->file.fd = fd; |
152 | 136 |
153 if (index[i].data[0] == '/') { | 137 if (index[i].data[0] == '/') { |
154 r->file.name.len = index[i].len; | 138 r->file.name.len = index[i].len; |
155 loc.len = index[i].len; | 139 loc.len = index[i].len; |
156 loc.data = index[i].data; | 140 loc.data = index[i].data; |
157 | 141 |
158 } else { | 142 } else { |
159 loc.len = r->uri.len + index[i].len; | 143 loc.len = r->uri.len + index[i].len; |
160 r->file.name.len = core_cf->doc_root.len + r->uri.len | 144 r->file.name.len = clcf->doc_root.len + r->uri.len |
161 + index[i].len; | 145 + index[i].len; |
162 } | 146 } |
163 | 147 |
164 /* STUB */ r->exten.len = 4; r->exten.data = "html"; | 148 /* STUB */ r->exten.len = 4; r->exten.data = "html"; |
165 | 149 |
176 r->path.data[r->path.len] = '\0'; | 160 r->path.data[r->path.len] = '\0'; |
177 | 161 |
178 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); | 162 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); |
179 | 163 |
180 #if 0 | 164 #if 0 |
181 if (r->path_err == NGX_EACCES) { | 165 if (r->path_err == NGX_EACCES) { |
182 return NGX_HTTP_FORBIDDEN; | 166 return NGX_HTTP_FORBIDDEN; |
183 } | 167 } |
184 #endif | 168 #endif |
185 | 169 |
186 if (ngx_file_type(r->path.data, &r->file.info) == -1) { | 170 if (ngx_file_type(r->path.data, &r->file.info) == -1) { |
187 | 171 |
188 r->path_err = ngx_errno; | 172 r->path_err = ngx_errno; |
224 | 208 |
225 static void *ngx_http_index_create_conf(ngx_pool_t *pool) | 209 static void *ngx_http_index_create_conf(ngx_pool_t *pool) |
226 { | 210 { |
227 ngx_http_index_conf_t *conf; | 211 ngx_http_index_conf_t *conf; |
228 | 212 |
229 ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), | 213 ngx_test_null(conf, ngx_palloc(pool, sizeof(ngx_http_index_conf_t)), |
230 NGX_CONF_ERROR); | 214 NGX_CONF_ERROR); |
231 | 215 |
232 ngx_test_null(conf->indices, | 216 ngx_init_array(conf->indices, pool, 3, sizeof(ngx_str_t), NGX_CONF_ERROR); |
233 ngx_create_array(pool, 3, sizeof(ngx_str_t)), | 217 conf->max_index_len = 0; |
234 NGX_CONF_ERROR); | |
235 | 218 |
236 return conf; | 219 return conf; |
237 } | 220 } |
238 | 221 |
239 | 222 |
240 /* STUB */ | 223 /* TODO: remove duplicate indices */ |
224 | |
241 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) | 225 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) |
242 { | 226 { |
243 #if 0 | 227 ngx_http_index_conf_t *prev = parent; |
244 ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; | 228 ngx_http_index_conf_t *conf = child; |
245 #endif | 229 |
246 ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; | 230 int i; |
247 ngx_str_t *index; | 231 ngx_str_t *index, *prev_index; |
248 | |
249 if (conf->max_index_len == 0) { | |
250 ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); | |
251 index->len = sizeof(NGX_HTTP_INDEX) - 1; | |
252 index->data = NGX_HTTP_INDEX; | |
253 conf->max_index_len = sizeof(NGX_HTTP_INDEX); | |
254 } | |
255 | |
256 /* FAIL: if first index is started with '/' */ | |
257 | |
258 return NULL; | |
259 } | |
260 | |
261 | |
262 #if 0 | |
263 static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) | |
264 { | |
265 ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; | |
266 ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; | |
267 ngx_str_t *index; | |
268 | 232 |
269 if (conf->max_index_len == 0) { | 233 if (conf->max_index_len == 0) { |
270 if (prev->max_index_len != 0) { | 234 if (prev->max_index_len != 0) { |
271 return prev; | 235 ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t)); |
272 } | 236 return NGX_CONF_OK; |
273 | 237 } |
274 ngx_test_null(index, ngx_push_array(conf->indices), NULL); | 238 |
275 index->len = sizeof(NGX_HTTP_INDEX) - 1; | 239 ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR); |
276 index->data = NGX_HTTP_INDEX; | 240 index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1; |
277 conf->max_index_len = sizeof(NGX_HTTP_INDEX); | 241 index->data = NGX_HTTP_DEFAULT_INDEX; |
278 } | 242 conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX); |
279 | 243 |
280 return conf; | 244 return NGX_CONF_OK; |
281 } | 245 } |
282 #endif | 246 |
247 if (prev->max_index_len != 0) { | |
248 | |
249 prev_index = prev->indices.elts; | |
250 for (i = 0; i < prev->indices.nelts; i++) { | |
251 ngx_test_null(index, ngx_push_array(&conf->indices), | |
252 NGX_CONF_ERROR); | |
253 index->len = prev_index[i].len; | |
254 index->data = prev_index[i].data; | |
255 } | |
256 } | |
257 | |
258 if (conf->max_index_len < prev->max_index_len) { | |
259 conf->max_index_len = prev->max_index_len; | |
260 } | |
261 | |
262 return NGX_CONF_OK; | |
263 } | |
264 | |
265 | |
266 /* TODO: check duplicate indices */ | |
283 | 267 |
284 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, | 268 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, |
285 char *conf) | 269 void *conf) |
286 { | 270 { |
287 ngx_http_index_conf_t *lcf = (ngx_http_index_conf_t *) conf; | 271 ngx_http_index_conf_t *icf = conf; |
288 int i; | 272 |
273 int i; | |
289 ngx_str_t *index, *value; | 274 ngx_str_t *index, *value; |
290 | 275 |
291 value = (ngx_str_t *) cf->args->elts; | 276 value = cf->args->elts; |
277 | |
278 if (value[1].data[0] == '/' && icf->indices.nelts == 0) { | |
279 ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, | |
280 "first index \"%s\" must not be absolute", value[1].data); | |
281 return ngx_conf_errstr; | |
282 } | |
283 | |
292 for (i = 1; i < cf->args->nelts; i++) { | 284 for (i = 1; i < cf->args->nelts; i++) { |
293 ngx_test_null(index, ngx_push_array(lcf->indices), NGX_CONF_ERROR); | 285 if (value[i].len == 0) { |
286 return "is invalid"; | |
287 } | |
288 | |
289 ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); | |
294 index->len = value[i].len; | 290 index->len = value[i].len; |
295 index->data = value[i].data; | 291 index->data = value[i].data; |
296 | 292 |
297 if (lcf->max_index_len < index->len) { | 293 if (icf->max_index_len < index->len + 1) { |
298 lcf->max_index_len = index->len; | 294 icf->max_index_len = index->len + 1; |
299 } | 295 } |
300 } | 296 } |
301 | 297 |
302 return NULL; | 298 return NULL; |
303 } | 299 } |