comparison src/http/modules/ngx_http_index_handler.c @ 201:267ea1d98683

nginx-0.0.1-2003-11-30-23:03:18 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 30 Nov 2003 20:03:18 +0000
parents abeaebe0a33c
children 74994aeef848
comparison
equal deleted inserted replaced
200:abeaebe0a33c 201:267ea1d98683
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_cache_hash_t *index_cache;
11 } ngx_http_index_conf_t; 11 } ngx_http_index_loc_conf_t;
12 12
13 13
14 typedef struct { 14 typedef struct {
15 int index; 15 ngx_int_t index;
16 unsigned tested:1; 16 char *last;
17 ngx_str_t path;
18 ngx_str_t redirect;
19 ngx_http_cache_t *cache;
20 unsigned tested:1;
17 } ngx_http_index_ctx_t; 21 } ngx_http_index_ctx_t;
18 22
19 23
20 #define NGX_HTTP_DEFAULT_INDEX "index.html" 24 #define NGX_HTTP_DEFAULT_INDEX "index.html"
21 25
24 ngx_http_index_ctx_t *ctx); 28 ngx_http_index_ctx_t *ctx);
25 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, 29 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
26 ngx_http_index_ctx_t *ctx, ngx_err_t err); 30 ngx_http_index_ctx_t *ctx, ngx_err_t err);
27 31
28 static int ngx_http_index_init(ngx_cycle_t *cycle); 32 static int ngx_http_index_init(ngx_cycle_t *cycle);
29 static void *ngx_http_index_create_conf(ngx_conf_t *cf); 33 static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
30 static char *ngx_http_index_merge_conf(ngx_conf_t *cf, 34 static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
31 void *parent, void *child); 35 void *parent, void *child);
32 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, 36 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
33 void *conf); 37 void *conf);
34 38
35 39
41 NGX_HTTP_LOC_CONF_OFFSET, 45 NGX_HTTP_LOC_CONF_OFFSET,
42 0, 46 0,
43 NULL }, 47 NULL },
44 48
45 { ngx_string("index_cache"), 49 { ngx_string("index_cache"),
46 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, 50 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3,
47 ngx_http_set_cache_slot, 51 ngx_http_set_cache_slot,
48 NGX_HTTP_LOC_CONF_OFFSET, 52 NGX_HTTP_LOC_CONF_OFFSET,
49 offsetof(ngx_http_index_conf_t, cache), 53 offsetof(ngx_http_index_loc_conf_t, index_cache),
50 NULL }, 54 NULL },
51 55
52 ngx_null_command 56 ngx_null_command
53 }; 57 };
54 58
60 NULL, /* init main configuration */ 64 NULL, /* init main configuration */
61 65
62 NULL, /* create server configuration */ 66 NULL, /* create server configuration */
63 NULL, /* merge server configuration */ 67 NULL, /* merge server configuration */
64 68
65 ngx_http_index_create_conf, /* create location configration */ 69 ngx_http_index_create_loc_conf, /* create location configration */
66 ngx_http_index_merge_conf /* merge location configration */ 70 ngx_http_index_merge_loc_conf /* merge location configration */
67 }; 71 };
68 72
69 73
70 ngx_module_t ngx_http_index_module = { 74 ngx_module_t ngx_http_index_module = {
71 NGX_MODULE, 75 NGX_MODULE,
87 * that path contains the usual file in place of the directory. 91 * that path contains the usual file in place of the directory.
88 */ 92 */
89 93
90 int ngx_http_index_handler(ngx_http_request_t *r) 94 int ngx_http_index_handler(ngx_http_request_t *r)
91 { 95 {
92 char *name, *file; 96 char *name;
93 uint32_t crc; 97 uint32_t crc;
94 ngx_int_t rc; 98 size_t len;
95 ngx_str_t redirect, *index; 99 ngx_fd_t fd;
96 ngx_err_t err; 100 ngx_int_t rc;
97 ngx_fd_t fd; 101 ngx_str_t *index;
98 ngx_http_cache_t *cache; 102 ngx_err_t err;
99 ngx_http_index_ctx_t *ctx; 103 ngx_log_t *log;
100 ngx_http_index_conf_t *ilcf; 104 ngx_http_index_ctx_t *ctx;
101 ngx_http_core_loc_conf_t *clcf; 105 ngx_http_core_loc_conf_t *clcf;
106 ngx_http_index_loc_conf_t *ilcf;
102 107
103 if (r->uri.data[r->uri.len - 1] != '/') { 108 if (r->uri.data[r->uri.len - 1] != '/') {
104 return NGX_DECLINED; 109 return NGX_DECLINED;
105 } 110 }
106 111
112 log = r->connection->log;
113
114 /*
115 * we use context because the handler supports an async file opening
116 * and thus can be called several times
117 */
118
119 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
107 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); 120 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, r->connection->log);
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, r->connection->log);
126
127 return ngx_http_internal_redirect(r, &redirect, NULL);
128 }
129
130 } else {
131 cache = NULL;
132 }
133 121
134 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); 122 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
135 if (ctx == NULL) { 123 if (ctx == NULL) {
136 ngx_http_create_ctx(r, ctx, ngx_http_index_module, 124 ngx_http_create_ctx(r, ctx, ngx_http_index_module,
137 sizeof(ngx_http_index_ctx_t), 125 sizeof(ngx_http_index_ctx_t),
138 NGX_HTTP_INTERNAL_SERVER_ERROR); 126 NGX_HTTP_INTERNAL_SERVER_ERROR);
139 } 127
140 128 if (ilcf->index_cache) {
141 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 129 ctx->cache = ngx_http_cache_get(ilcf->index_cache, NULL,
142 130 &r->uri, &crc);
143 if (r->path.data == NULL) { 131
144 r->path_allocated = clcf->doc_root.len + r->uri.len 132 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
145 + ilcf->max_index_len; 133 "http index cache get: " PTR_FMT, ctx->cache);
146 ngx_test_null(r->path.data, 134
147 ngx_palloc(r->pool, r->path_allocated), 135 if (ctx->cache && ctx->cache->valid) {
148 NGX_HTTP_INTERNAL_SERVER_ERROR); 136
149 137 ctx->cache->accessed = ngx_cached_time;
150 redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data, 138
151 clcf->doc_root.len); 139 ctx->redirect.len = ctx->cache->data.value.len;
152 file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1); 140 ctx->redirect.data = ngx_palloc(r->pool, ctx->redirect.len + 1);
153 r->path.len = file - r->path.data; 141 if (ctx->redirect.data == NULL) {
154 142 ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
155 } else{ 143 return NGX_HTTP_INTERNAL_SERVER_ERROR;
156 redirect.data = r->path.data + r->path.len; 144 }
157 file = redirect.data + r->uri.len; 145
146 ngx_memcpy(ctx->redirect.data, ctx->cache->data.value.data,
147 ctx->redirect.len + 1);
148 ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
149
150 return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
151 }
152
153 } else {
154 ctx->cache = NULL;
155 }
156
157 len = clcf->doc_root.len + r->uri.len + ilcf->max_index_len;
158 if (!(ctx->path.data = ngx_palloc(r->pool, len))) {
159 return NGX_HTTP_INTERNAL_SERVER_ERROR;
160 }
161
162 ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->doc_root.data,
163 clcf->doc_root.len);
164 ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data,
165 r->uri.len + 1);
166 ctx->path.len = ctx->last - ctx->path.data;
158 } 167 }
159 168
160 index = ilcf->indices.elts; 169 index = ilcf->indices.elts;
161 for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) { 170 for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
162 171
163 if (index[ctx->index].data[0] == '/') { 172 if (index[ctx->index].data[0] == '/') {
164 name = index[ctx->index].data; 173 name = index[ctx->index].data;
165 174
166 } else { 175 } else {
167 ngx_memcpy(file, index[ctx->index].data, index[ctx->index].len + 1); 176 ngx_memcpy(ctx->last, index[ctx->index].data,
168 name = r->path.data; 177 index[ctx->index].len + 1);
178 name = ctx->path.data;
169 } 179 }
170 180
171 fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN); 181 fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
172 182
173 if (fd == (ngx_fd_t) NGX_AGAIN) { 183 if (fd == (ngx_fd_t) NGX_AGAIN) {
175 } 185 }
176 186
177 if (fd == NGX_INVALID_FILE) { 187 if (fd == NGX_INVALID_FILE) {
178 err = ngx_errno; 188 err = ngx_errno;
179 189
180 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, 190 ngx_log_error(NGX_LOG_DEBUG, log, err,
181 "DEBUG: " ngx_open_file_n " %s failed", name); 191 "debug: " ngx_open_file_n " %s failed", name);
182 192
183 if (err == NGX_ENOTDIR) { 193 if (err == NGX_ENOTDIR) {
184 return ngx_http_index_error(r, ctx, err); 194 return ngx_http_index_error(r, ctx, err);
185 195
186 } else if (err == NGX_EACCES) { 196 } else if (err == NGX_EACCES) {
199 209
200 if (err == NGX_ENOENT) { 210 if (err == NGX_ENOENT) {
201 continue; 211 continue;
202 } 212 }
203 213
204 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, 214 ngx_log_error(NGX_LOG_ERR, log, err,
205 ngx_open_file_n " %s failed", name); 215 ngx_open_file_n " %s failed", name);
206 216
207 return NGX_HTTP_INTERNAL_SERVER_ERROR; 217 return NGX_HTTP_INTERNAL_SERVER_ERROR;
208 } 218 }
219
220
221 /* STUB: open file cache */
209 222
210 r->file.name.data = name; 223 r->file.name.data = name;
211 r->file.fd = fd; 224 r->file.fd = fd;
212 225
213 if (index[ctx->index].data[0] == '/') { 226 if (index[ctx->index].data[0] == '/') {
214 r->file.name.len = index[ctx->index].len; 227 r->file.name.len = index[ctx->index].len;
215 redirect.len = index[ctx->index].len; 228 ctx->redirect.len = index[ctx->index].len;
216 redirect.data = index[ctx->index].data; 229 ctx->redirect.data = index[ctx->index].data;
217 230
218 } else { 231 } else {
219 redirect.len = r->uri.len + index[ctx->index].len; 232 ctx->redirect.len = r->uri.len + index[ctx->index].len;
220 r->file.name.len = clcf->doc_root.len + r->uri.len 233 r->file.name.len = clcf->doc_root.len + r->uri.len
221 + index[ctx->index].len; 234 + index[ctx->index].len;
222 } 235 }
223 236
224 if (ilcf->cache) { 237 /**/
225 238
226 if (cache) { 239
227 if (redirect.len == cache->data.value.len 240 if (ilcf->index_cache) {
228 && ngx_memcmp(cache->data.value.data, redirect.data, 241
229 redirect.len) == 0) 242 if (ctx->cache) {
243 if (ctx->redirect.len == ctx->cache->data.value.len
244 && ngx_memcmp(ctx->cache->data.value.data,
245 ctx->redirect.data, ctx->redirect.len) == 0)
230 { 246 {
231 cache->accessed = ngx_cached_time; 247 ctx->cache->accessed = ngx_cached_time;
232 cache->updated = ngx_cached_time; 248 ctx->cache->updated = ngx_cached_time;
233 ngx_http_cache_unlock(ilcf->cache, cache, 249 ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
234 r->connection->log); 250
235 251 return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
236 return ngx_http_internal_redirect(r, &redirect, NULL);
237
238 } else {
239 if (redirect.len > cache->data.value.len) {
240 ngx_free(cache->data.value.data);
241 cache->data.value.data = NULL;
242 }
243 } 252 }
244 } 253 }
245 254
246 if (cache == NULL) { 255 ctx->redirect.len++;
247 cache = ngx_http_cache_alloc(ilcf->cache, &r->uri, crc, 256 ctx->cache = ngx_http_cache_alloc(ilcf->index_cache, ctx->cache,
248 r->connection->log); 257 NULL, &r->uri, crc,
249 } 258 &ctx->redirect, log);
250 259 ctx->redirect.len--;
251 ngx_log_debug(r->connection->log, "index cache alloc: %x" _ cache); 260
252 261 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
253 if (cache) { 262 "http index cache alloc: " PTR_FMT, ctx->cache);
254 cache->fd = NGX_INVALID_FILE; 263
255 cache->accessed = ngx_cached_time; 264 if (ctx->cache) {
256 cache->last_modified = 0; 265 ctx->cache->fd = NGX_INVALID_FILE;
257 cache->updated = ngx_cached_time; 266 ctx->cache->accessed = ngx_cached_time;
258 267 ctx->cache->last_modified = 0;
259 cache->data.value.len = redirect.len; 268 ctx->cache->updated = ngx_cached_time;
260 if (cache->data.value.data == NULL) { 269 ctx->cache->valid = 1;
261 cache->data.value.data = ngx_alloc(redirect.len + 1, 270 ctx->cache->memory = 1;
262 r->connection->log); 271 ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
263 if (cache->data.value.data == NULL) { 272 }
264 return NGX_HTTP_INTERNAL_SERVER_ERROR; 273 }
265 } 274
266 } 275 return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
267
268 ngx_memcpy(cache->data.value.data, redirect.data,
269 redirect.len + 1);
270 }
271 }
272
273 if (cache) {
274 ngx_http_cache_unlock(ilcf->cache, cache, r->connection->log);
275 }
276
277 return ngx_http_internal_redirect(r, &redirect, NULL);
278 } 276 }
279 277
280 return NGX_DECLINED; 278 return NGX_DECLINED;
281 } 279 }
282 280
284 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, 282 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
285 ngx_http_index_ctx_t *ctx) 283 ngx_http_index_ctx_t *ctx)
286 { 284 {
287 ngx_err_t err; 285 ngx_err_t err;
288 286
289 r->path.data[r->path.len - 1] = '\0'; 287 ctx->path.data[ctx->path.len - 1] = '\0';
290 r->path.data[r->path.len] = '\0'; 288 ctx->path.data[ctx->path.len] = '\0';
291 289
292 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); 290 ngx_log_debug(r->connection->log, "IS_DIR: %s" _ ctx->path.data);
293 291
294 if (ngx_file_info(r->path.data, &r->file.info) == -1) { 292 if (ngx_file_info(ctx->path.data, &r->file.info) == -1) {
295 293
296 err = ngx_errno; 294 err = ngx_errno;
297 295
298 if (err == NGX_ENOENT) { 296 if (err == NGX_ENOENT) {
299 r->path.data[r->path.len - 1] = '/'; 297 ctx->path.data[ctx->path.len - 1] = '/';
300 return ngx_http_index_error(r, ctx, err); 298 return ngx_http_index_error(r, ctx, err);
301 } 299 }
302 300
303 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, 301 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
304 ngx_file_info_n " %s failed", r->path.data); 302 ngx_file_info_n " %s failed", ctx->path.data);
305 303
306 return NGX_HTTP_INTERNAL_SERVER_ERROR; 304 return NGX_HTTP_INTERNAL_SERVER_ERROR;
307 } 305 }
308 306
309 r->path.data[r->path.len - 1] = '/'; 307 ctx->path.data[ctx->path.len - 1] = '/';
310 308
311 if (ngx_is_dir(&r->file.info)) { 309 if (ngx_is_dir(&r->file.info)) {
312 return NGX_OK; 310 return NGX_OK;
313 } 311 }
314 312
320 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, 318 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
321 ngx_http_index_ctx_t *ctx, ngx_err_t err) 319 ngx_http_index_ctx_t *ctx, ngx_err_t err)
322 { 320 {
323 if (err == NGX_EACCES) { 321 if (err == NGX_EACCES) {
324 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, 322 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
325 "\"%s\" is forbidden", r->path.data); 323 "\"%s\" is forbidden", ctx->path.data);
326 324
327 return NGX_HTTP_FORBIDDEN; 325 return NGX_HTTP_FORBIDDEN;
328 } 326 }
329 327
330 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, 328 ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
331 "\"%s\" is not found", r->path.data); 329 "\"%s\" is not found", ctx->path.data);
332 return NGX_HTTP_NOT_FOUND; 330 return NGX_HTTP_NOT_FOUND;
333 } 331 }
334 332
335 333
336 static int ngx_http_index_init(ngx_cycle_t *cycle) 334 static int ngx_http_index_init(ngx_cycle_t *cycle)
340 ngx_http_core_main_conf_t *cmcf; 338 ngx_http_core_main_conf_t *cmcf;
341 339
342 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; 340 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
343 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; 341 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
344 342
345 ngx_test_null(h, ngx_push_array( 343 h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
346 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers), 344 if (h == NULL) {
347 NGX_ERROR); 345 return NGX_ERROR;
346 }
347
348 *h = ngx_http_index_handler; 348 *h = ngx_http_index_handler;
349 349
350 return NGX_OK; 350 return NGX_OK;
351 } 351 }
352 352
353 353
354 static void *ngx_http_index_create_conf(ngx_conf_t *cf) 354 static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf)
355 { 355 {
356 ngx_http_index_conf_t *conf; 356 ngx_http_index_loc_conf_t *conf;
357 357
358 ngx_test_null(conf, ngx_palloc(cf->pool, sizeof(ngx_http_index_conf_t)), 358 ngx_test_null(conf, ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t)),
359 NGX_CONF_ERROR); 359 NGX_CONF_ERROR);
360 360
361 ngx_init_array(conf->indices, cf->pool, 3, sizeof(ngx_str_t), 361 ngx_init_array(conf->indices, cf->pool, 3, sizeof(ngx_str_t),
362 NGX_CONF_ERROR); 362 NGX_CONF_ERROR);
363 conf->max_index_len = 0; 363 conf->max_index_len = 0;
364 364
365 conf->cache = NULL; 365 conf->index_cache = NULL;
366 366
367 return conf; 367 return conf;
368 } 368 }
369 369
370 370
371 /* TODO: remove duplicate indices */ 371 /* TODO: remove duplicate indices */
372 372
373 static char *ngx_http_index_merge_conf(ngx_conf_t *cf, 373 static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
374 void *parent, void *child) 374 void *parent, void *child)
375 { 375 {
376 ngx_http_index_conf_t *prev = parent; 376 ngx_http_index_loc_conf_t *prev = parent;
377 ngx_http_index_conf_t *conf = child; 377 ngx_http_index_loc_conf_t *conf = child;
378 378
379 int i; 379 int i;
380 ngx_str_t *index, *prev_index; 380 ngx_str_t *index, *prev_index;
381 381
382 if (conf->max_index_len == 0) { 382 if (conf->max_index_len == 0) {
383 if (prev->max_index_len != 0) { 383 if (prev->max_index_len != 0) {
384 ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t)); 384 ngx_memcpy(conf, prev, sizeof(ngx_http_index_loc_conf_t));
385 return NGX_CONF_OK; 385 return NGX_CONF_OK;
386 } 386 }
387 387
388 ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR); 388 ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR);
389 index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1; 389 index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1;
406 406
407 if (conf->max_index_len < prev->max_index_len) { 407 if (conf->max_index_len < prev->max_index_len) {
408 conf->max_index_len = prev->max_index_len; 408 conf->max_index_len = prev->max_index_len;
409 } 409 }
410 410
411 if (conf->cache == NULL) { 411 if (conf->index_cache == NULL) {
412 conf->cache = prev->cache; 412 conf->index_cache = prev->index_cache;
413 } 413 }
414 414
415 return NGX_CONF_OK; 415 return NGX_CONF_OK;
416 } 416 }
417 417
419 /* TODO: warn about duplicate indices */ 419 /* TODO: warn about duplicate indices */
420 420
421 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, 421 static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
422 void *conf) 422 void *conf)
423 { 423 {
424 ngx_http_index_conf_t *ilcf = conf; 424 ngx_http_index_loc_conf_t *ilcf = conf;
425 425
426 int i; 426 int i;
427 ngx_str_t *index, *value; 427 ngx_str_t *index, *value;
428 428
429 value = cf->args->elts; 429 value = cf->args->elts;