comparison src/http/modules/ngx_http_index_handler.c @ 199:a65b630b3a66

nginx-0.0.1-2003-11-28-11:40:40 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 28 Nov 2003 08:40:40 +0000
parents c1f3a3c7c5db
children abeaebe0a33c
comparison
equal deleted inserted replaced
198:34995c5ec6c4 199:a65b630b3a66
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_http.h> 4 #include <ngx_http.h>
5 5
6 6
7 typedef struct { 7 typedef struct {
8 ngx_array_t indices; 8 ngx_array_t indices;
9 size_t max_index_len; 9 size_t max_index_len;
10 ngx_http_cache_hash_t *cache;
10 } ngx_http_index_conf_t; 11 } ngx_http_index_conf_t;
11 12
12 13
13 typedef struct { 14 typedef struct {
14 int index; 15 int index;
17 18
18 19
19 #define NGX_HTTP_DEFAULT_INDEX "index.html" 20 #define NGX_HTTP_DEFAULT_INDEX "index.html"
20 21
21 22
22 static int ngx_http_index_test_dir(ngx_http_request_t *r, 23 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
23 ngx_http_index_ctx_t *ctx); 24 ngx_http_index_ctx_t *ctx);
24 static int ngx_http_index_error(ngx_http_request_t *r, 25 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
25 ngx_http_index_ctx_t *ctx, ngx_err_t err); 26 ngx_http_index_ctx_t *ctx, ngx_err_t err);
26 27
27 static int ngx_http_index_init(ngx_cycle_t *cycle); 28 static int ngx_http_index_init(ngx_cycle_t *cycle);
28 static void *ngx_http_index_create_conf(ngx_conf_t *cf); 29 static void *ngx_http_index_create_conf(ngx_conf_t *cf);
29 static char *ngx_http_index_merge_conf(ngx_conf_t *cf, 30 static char *ngx_http_index_merge_conf(ngx_conf_t *cf,
30 void *parent, void *child); 31 void *parent, void *child);
31 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, 32 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
32 void *conf); 33 void *conf);
33 34
34 35
35 static ngx_command_t ngx_http_index_commands[] = { 36 static ngx_command_t ngx_http_index_commands[] = {
36 37
37 {ngx_string("index"), 38 { ngx_string("index"),
38 NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, 39 NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
39 ngx_http_index_set_index, 40 ngx_http_index_set_index,
40 NGX_HTTP_LOC_CONF_OFFSET, 41 NGX_HTTP_LOC_CONF_OFFSET,
41 0, 42 0,
42 NULL}, 43 NULL },
43 44
44 ngx_null_command 45 { ngx_string("index_cache"),
46 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
47 ngx_http_set_cache_slot,
48 NGX_HTTP_LOC_CONF_OFFSET,
49 offsetof(ngx_http_index_conf_t, cache),
50 NULL },
51
52 ngx_null_command
45 }; 53 };
46 54
47 55
48 ngx_http_module_t ngx_http_index_module_ctx = { 56 ngx_http_module_t ngx_http_index_module_ctx = {
49 NULL, /* pre conf */ 57 NULL, /* pre conf */
79 * that path contains the usual file in place of the directory. 87 * that path contains the usual file in place of the directory.
80 */ 88 */
81 89
82 int ngx_http_index_handler(ngx_http_request_t *r) 90 int ngx_http_index_handler(ngx_http_request_t *r)
83 { 91 {
84 int rc;
85 char *name, *file; 92 char *name, *file;
93 uint32_t crc;
94 ngx_int_t rc;
86 ngx_str_t redirect, *index; 95 ngx_str_t redirect, *index;
87 ngx_err_t err; 96 ngx_err_t err;
88 ngx_fd_t fd; 97 ngx_fd_t fd;
98 ngx_http_cache_t *cache;
89 ngx_http_index_ctx_t *ctx; 99 ngx_http_index_ctx_t *ctx;
90 ngx_http_index_conf_t *icf; 100 ngx_http_index_conf_t *ilcf;
91 ngx_http_core_loc_conf_t *clcf; 101 ngx_http_core_loc_conf_t *clcf;
92 102
93 if (r->uri.data[r->uri.len - 1] != '/') { 103 if (r->uri.data[r->uri.len - 1] != '/') {
94 return NGX_DECLINED; 104 return NGX_DECLINED;
105 }
106
107 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
108
109 if (ilcf->cache) {
110 cache = ngx_http_cache_get(ilcf->cache, &r->uri, &crc);
111
112 ngx_log_debug(r->connection->log, "index cache get: %x" _ cache);
113
114 if (cache && ilcf->cache->update >= ngx_cached_time - cache->updated) {
115
116 cache->accessed = ngx_cached_time;
117
118 redirect.len = cache->data.value.len;
119 if (!(redirect.data = ngx_palloc(r->pool, redirect.len + 1))) {
120 ngx_http_cache_unlock(ilcf->cache, cache);
121 return NGX_HTTP_INTERNAL_SERVER_ERROR;
122 }
123
124 ngx_memcpy(redirect.data, cache->data.value.data, redirect.len + 1);
125 ngx_http_cache_unlock(ilcf->cache, cache);
126
127 return ngx_http_internal_redirect(r, &redirect, NULL);
128 }
129
130 } else {
131 cache = NULL;
95 } 132 }
96 133
97 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); 134 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
98 if (ctx == NULL) { 135 if (ctx == NULL) {
99 ngx_http_create_ctx(r, ctx, ngx_http_index_module, 136 ngx_http_create_ctx(r, ctx, ngx_http_index_module,
100 sizeof(ngx_http_index_ctx_t), 137 sizeof(ngx_http_index_ctx_t),
101 NGX_HTTP_INTERNAL_SERVER_ERROR); 138 NGX_HTTP_INTERNAL_SERVER_ERROR);
102 } 139 }
103 140
104 icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
105 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 141 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
106 142
107 if (r->path.data == NULL) { 143 if (r->path.data == NULL) {
108 r->path_allocated = clcf->doc_root.len + r->uri.len 144 r->path_allocated = clcf->doc_root.len + r->uri.len
109 + icf->max_index_len; 145 + ilcf->max_index_len;
110 ngx_test_null(r->path.data, 146 ngx_test_null(r->path.data,
111 ngx_palloc(r->pool, r->path_allocated), 147 ngx_palloc(r->pool, r->path_allocated),
112 NGX_HTTP_INTERNAL_SERVER_ERROR); 148 NGX_HTTP_INTERNAL_SERVER_ERROR);
113 149
114 redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data, 150 redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data,
119 } else{ 155 } else{
120 redirect.data = r->path.data + r->path.len; 156 redirect.data = r->path.data + r->path.len;
121 file = redirect.data + r->uri.len; 157 file = redirect.data + r->uri.len;
122 } 158 }
123 159
124 index = icf->indices.elts; 160 index = ilcf->indices.elts;
125 for (/* void */; ctx->index < icf->indices.nelts; ctx->index++) { 161 for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
126 162
127 if (index[ctx->index].data[0] == '/') { 163 if (index[ctx->index].data[0] == '/') {
128 name = index[ctx->index].data; 164 name = index[ctx->index].data;
129 165
130 } else { 166 } else {
183 redirect.len = r->uri.len + index[ctx->index].len; 219 redirect.len = r->uri.len + index[ctx->index].len;
184 r->file.name.len = clcf->doc_root.len + r->uri.len 220 r->file.name.len = clcf->doc_root.len + r->uri.len
185 + index[ctx->index].len; 221 + index[ctx->index].len;
186 } 222 }
187 223
224 if (ilcf->cache) {
225
226 if (cache) {
227 if (redirect.len == cache->data.value.len
228 && ngx_memcmp(cache->data.value.data, redirect.data,
229 redirect.len) == 0)
230 {
231 cache->accessed = ngx_cached_time;
232 cache->updated = ngx_cached_time;
233 ngx_http_cache_unlock(ilcf->cache, cache);
234
235 return ngx_http_internal_redirect(r, &redirect, NULL);
236
237 } else {
238 if (redirect.len > cache->data.value.len) {
239 ngx_free(cache->data.value.data);
240 cache->data.value.data = NULL;
241 }
242 }
243 }
244
245 if (cache == NULL) {
246 cache = ngx_http_cache_alloc(ilcf->cache, &r->uri, crc,
247 r->connection->log);
248 }
249
250 ngx_log_debug(r->connection->log, "index cache alloc: %x" _ cache);
251
252 if (cache) {
253 cache->fd = NGX_INVALID_FILE;
254 cache->accessed = ngx_cached_time;
255 cache->last_modified = 0;
256 cache->updated = ngx_cached_time;
257
258 cache->data.value.len = redirect.len;
259 if (cache->data.value.data == NULL) {
260 cache->data.value.data = ngx_alloc(redirect.len + 1,
261 r->connection->log);
262 if (cache->data.value.data == NULL) {
263 return NGX_HTTP_INTERNAL_SERVER_ERROR;
264 }
265 }
266
267 ngx_memcpy(cache->data.value.data, redirect.data,
268 redirect.len + 1);
269 }
270 }
271
272 if (cache) {
273 ngx_http_cache_unlock(ilcf->cache, cache);
274 }
275
188 return ngx_http_internal_redirect(r, &redirect, NULL); 276 return ngx_http_internal_redirect(r, &redirect, NULL);
189 } 277 }
190 278
191 return NGX_DECLINED; 279 return NGX_DECLINED;
192 } 280 }
193 281
194 282
195 static int ngx_http_index_test_dir(ngx_http_request_t *r, 283 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
196 ngx_http_index_ctx_t *ctx) 284 ngx_http_index_ctx_t *ctx)
197 { 285 {
198 ngx_err_t err; 286 ngx_err_t err;
199 287
200 r->path.data[r->path.len - 1] = '\0'; 288 r->path.data[r->path.len - 1] = '\0';
201 r->path.data[r->path.len] = '\0'; 289 r->path.data[r->path.len] = '\0';
226 /* THINK: not reached ??? */ 314 /* THINK: not reached ??? */
227 return ngx_http_index_error(r, ctx, 0); 315 return ngx_http_index_error(r, ctx, 0);
228 } 316 }
229 317
230 318
231 static int ngx_http_index_error(ngx_http_request_t *r, 319 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
232 ngx_http_index_ctx_t *ctx, ngx_err_t err) 320 ngx_http_index_ctx_t *ctx, ngx_err_t err)
233 { 321 {
234 if (err == NGX_EACCES) { 322 if (err == NGX_EACCES) {
235 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, 323 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
236 "\"%s\" is forbidden", r->path.data); 324 "\"%s\" is forbidden", r->path.data);
237 325
270 NGX_CONF_ERROR); 358 NGX_CONF_ERROR);
271 359
272 ngx_init_array(conf->indices, cf->pool, 3, sizeof(ngx_str_t), 360 ngx_init_array(conf->indices, cf->pool, 3, sizeof(ngx_str_t),
273 NGX_CONF_ERROR); 361 NGX_CONF_ERROR);
274 conf->max_index_len = 0; 362 conf->max_index_len = 0;
363
364 conf->cache = NULL;
275 365
276 return conf; 366 return conf;
277 } 367 }
278 368
279 369
315 405
316 if (conf->max_index_len < prev->max_index_len) { 406 if (conf->max_index_len < prev->max_index_len) {
317 conf->max_index_len = prev->max_index_len; 407 conf->max_index_len = prev->max_index_len;
318 } 408 }
319 409
410 if (conf->cache == NULL) {
411 conf->cache = prev->cache;
412 }
413
320 return NGX_CONF_OK; 414 return NGX_CONF_OK;
321 } 415 }
322 416
323 417
324 /* TODO: warn about duplicate indices */ 418 /* TODO: warn about duplicate indices */
325 419
326 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, 420 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
327 void *conf) 421 void *conf)
328 { 422 {
329 ngx_http_index_conf_t *icf = conf; 423 ngx_http_index_conf_t *ilcf = conf;
330 424
331 int i; 425 int i;
332 ngx_str_t *index, *value; 426 ngx_str_t *index, *value;
333 427
334 value = cf->args->elts; 428 value = cf->args->elts;
335 429
336 if (value[1].data[0] == '/' && icf->indices.nelts == 0) { 430 if (value[1].data[0] == '/' && ilcf->indices.nelts == 0) {
337 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 431 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
338 "first index \"%s\" in \"%s\" directive " 432 "first index \"%s\" in \"%s\" directive "
339 "must not be absolute", 433 "must not be absolute",
340 value[1].data, cmd->name.data); 434 value[1].data, cmd->name.data);
341 return NGX_CONF_ERROR; 435 return NGX_CONF_ERROR;
347 "index \"%s\" in \"%s\" directive is invalid", 441 "index \"%s\" in \"%s\" directive is invalid",
348 value[1].data, cmd->name.data); 442 value[1].data, cmd->name.data);
349 return NGX_CONF_ERROR; 443 return NGX_CONF_ERROR;
350 } 444 }
351 445
352 ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); 446 ngx_test_null(index, ngx_push_array(&ilcf->indices), NGX_CONF_ERROR);
353 index->len = value[i].len; 447 index->len = value[i].len;
354 index->data = value[i].data; 448 index->data = value[i].data;
355 449
356 if (icf->max_index_len < index->len + 1) { 450 if (ilcf->max_index_len < index->len + 1) {
357 icf->max_index_len = index->len + 1; 451 ilcf->max_index_len = index->len + 1;
358 } 452 }
359 } 453 }
360 454
361 return NGX_CONF_OK; 455 return NGX_CONF_OK;
362 } 456 }