Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_autoindex_module.c @ 644:6f21ae02fb01 NGINX_1_1_6
nginx 1.1.6
*) Change in internal API: now module context data are cleared while
internal redirect to named location.
Requested by Yichun Zhang.
*) Change: if a server in an upstream failed, only one request will be
sent to it after fail_timeout; the server will be considered alive if
it will successfully respond to the request.
*) Change: now the 0x7F-0x1F characters are escaped as \xXX in an
access_log.
*) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support
the following additional values: X-Accel-Limit-Rate,
X-Accel-Buffering, X-Accel-Charset.
*) Feature: decrease of memory consumption if SSL is used.
*) Bugfix: some UTF-8 characters were processed incorrectly.
Thanks to Alexey Kuts.
*) Bugfix: the ngx_http_rewrite_module directives specified at "server"
level were executed twice if no matching locations were defined.
*) Bugfix: a socket leak might occurred if "aio sendfile" was used.
*) Bugfix: connections with fast clients might be closed after
send_timeout if file AIO was used.
*) Bugfix: in the ngx_http_autoindex_module.
*) Bugfix: the module ngx_http_mp4_module did not support seeking on
32-bit platforms.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 17 Oct 2011 00:00:00 +0400 |
parents | ff463db0be31 |
children | d0f7a625f27c |
comparison
equal
deleted
inserted
replaced
643:a4bb0b481f6c | 644:6f21ae02fb01 |
---|---|
24 | 24 |
25 typedef struct { | 25 typedef struct { |
26 ngx_str_t name; | 26 ngx_str_t name; |
27 size_t utf_len; | 27 size_t utf_len; |
28 size_t escape; | 28 size_t escape; |
29 size_t escape_html; | |
29 | 30 |
30 unsigned dir:1; | 31 unsigned dir:1; |
31 unsigned colon:1; | |
32 | 32 |
33 time_t mtime; | 33 time_t mtime; |
34 off_t size; | 34 off_t size; |
35 } ngx_http_autoindex_entry_t; | 35 } ngx_http_autoindex_entry_t; |
36 | 36 |
136 static ngx_int_t | 136 static ngx_int_t |
137 ngx_http_autoindex_handler(ngx_http_request_t *r) | 137 ngx_http_autoindex_handler(ngx_http_request_t *r) |
138 { | 138 { |
139 u_char *last, *filename, scale; | 139 u_char *last, *filename, scale; |
140 off_t length; | 140 off_t length; |
141 size_t len, utf_len, allocated, root; | 141 size_t len, char_len, escape_html, allocated, root; |
142 ngx_tm_t tm; | 142 ngx_tm_t tm; |
143 ngx_err_t err; | 143 ngx_err_t err; |
144 ngx_buf_t *b; | 144 ngx_buf_t *b; |
145 ngx_int_t rc, size; | 145 ngx_int_t rc, size; |
146 ngx_str_t path; | 146 ngx_str_t path; |
336 } | 336 } |
337 | 337 |
338 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); | 338 ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1); |
339 | 339 |
340 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, | 340 entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len, |
341 NGX_ESCAPE_HTML); | 341 NGX_ESCAPE_URI_COMPONENT); |
342 | |
343 entry->escape_html = ngx_escape_html(NULL, entry->name.data, | |
344 entry->name.len); | |
342 | 345 |
343 if (utf8) { | 346 if (utf8) { |
344 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); | 347 entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len); |
345 } else { | 348 } else { |
346 entry->utf_len = len; | 349 entry->utf_len = len; |
347 } | 350 } |
348 | 351 |
349 entry->colon = (ngx_strchr(entry->name.data, ':') != NULL); | |
350 | |
351 entry->dir = ngx_de_is_dir(&dir); | 352 entry->dir = ngx_de_is_dir(&dir); |
352 entry->mtime = ngx_de_mtime(&dir); | 353 entry->mtime = ngx_de_mtime(&dir); |
353 entry->size = ngx_de_size(&dir); | 354 entry->size = ngx_de_size(&dir); |
354 } | 355 } |
355 | 356 |
356 if (ngx_close_dir(&dir) == NGX_ERROR) { | 357 if (ngx_close_dir(&dir) == NGX_ERROR) { |
357 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, | 358 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, |
358 ngx_close_dir_n " \"%s\" failed", &path); | 359 ngx_close_dir_n " \"%s\" failed", &path); |
359 } | 360 } |
360 | 361 |
362 escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len); | |
363 | |
361 len = sizeof(title) - 1 | 364 len = sizeof(title) - 1 |
362 + r->uri.len | 365 + r->uri.len + escape_html |
363 + sizeof(header) - 1 | 366 + sizeof(header) - 1 |
364 + r->uri.len | 367 + r->uri.len + escape_html |
365 + sizeof("</h1>") - 1 | 368 + sizeof("</h1>") - 1 |
366 + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1 | 369 + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1 |
367 + sizeof("</pre><hr>") - 1 | 370 + sizeof("</pre><hr>") - 1 |
368 + sizeof(tail) - 1; | 371 + sizeof(tail) - 1; |
369 | 372 |
371 for (i = 0; i < entries.nelts; i++) { | 374 for (i = 0; i < entries.nelts; i++) { |
372 len += sizeof("<a href=\"") - 1 | 375 len += sizeof("<a href=\"") - 1 |
373 + entry[i].name.len + entry[i].escape | 376 + entry[i].name.len + entry[i].escape |
374 + 1 /* 1 is for "/" */ | 377 + 1 /* 1 is for "/" */ |
375 + sizeof("\">") - 1 | 378 + sizeof("\">") - 1 |
376 + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2 | 379 + entry[i].name.len - entry[i].utf_len |
380 + entry[i].escape_html | |
377 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 | 381 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 |
378 + sizeof("</a>") - 1 | 382 + sizeof("</a>") - 1 |
379 + sizeof(" 28-Sep-1970 12:00 ") - 1 | 383 + sizeof(" 28-Sep-1970 12:00 ") - 1 |
380 + 20 /* the file size */ | 384 + 20 /* the file size */ |
381 + 2; | 385 + 2; |
391 sizeof(ngx_http_autoindex_entry_t), | 395 sizeof(ngx_http_autoindex_entry_t), |
392 ngx_http_autoindex_cmp_entries); | 396 ngx_http_autoindex_cmp_entries); |
393 } | 397 } |
394 | 398 |
395 b->last = ngx_cpymem(b->last, title, sizeof(title) - 1); | 399 b->last = ngx_cpymem(b->last, title, sizeof(title) - 1); |
396 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); | 400 |
397 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); | 401 if (escape_html) { |
398 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); | 402 b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len); |
403 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); | |
404 b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len); | |
405 | |
406 } else { | |
407 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); | |
408 b->last = ngx_cpymem(b->last, header, sizeof(header) - 1); | |
409 b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len); | |
410 } | |
411 | |
399 b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1); | 412 b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1); |
400 | 413 |
401 b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF, | 414 b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF, |
402 sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1); | 415 sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1); |
403 | 416 |
404 tp = ngx_timeofday(); | 417 tp = ngx_timeofday(); |
405 | 418 |
406 for (i = 0; i < entries.nelts; i++) { | 419 for (i = 0; i < entries.nelts; i++) { |
407 b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1); | 420 b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1); |
408 | 421 |
409 if (entry[i].colon) { | |
410 *b->last++ = '.'; | |
411 *b->last++ = '/'; | |
412 } | |
413 | |
414 if (entry[i].escape) { | 422 if (entry[i].escape) { |
415 ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len, | 423 ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len, |
416 NGX_ESCAPE_HTML); | 424 NGX_ESCAPE_URI_COMPONENT); |
417 | 425 |
418 b->last += entry[i].name.len + entry[i].escape; | 426 b->last += entry[i].name.len + entry[i].escape; |
419 | 427 |
420 } else { | 428 } else { |
421 b->last = ngx_cpymem(b->last, entry[i].name.data, | 429 b->last = ngx_cpymem(b->last, entry[i].name.data, |
431 | 439 |
432 len = entry[i].utf_len; | 440 len = entry[i].utf_len; |
433 | 441 |
434 if (entry[i].name.len != len) { | 442 if (entry[i].name.len != len) { |
435 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { | 443 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { |
436 utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1; | 444 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1; |
437 | 445 |
438 } else { | 446 } else { |
439 utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1; | 447 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1; |
440 } | 448 } |
441 | 449 |
450 last = b->last; | |
442 b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data, | 451 b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data, |
443 utf_len, entry[i].name.len + 1); | 452 char_len, entry[i].name.len + 1); |
453 | |
454 if (entry[i].escape_html) { | |
455 b->last = (u_char *) ngx_escape_html(last, entry[i].name.data, | |
456 b->last - last); | |
457 } | |
458 | |
444 last = b->last; | 459 last = b->last; |
445 | 460 |
446 } else { | 461 } else { |
447 b->last = ngx_cpystrn(b->last, entry[i].name.data, | 462 if (entry[i].escape_html) { |
448 NGX_HTTP_AUTOINDEX_NAME_LEN + 1); | 463 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { |
449 last = b->last - 3; | 464 char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3; |
465 | |
466 } else { | |
467 char_len = len; | |
468 } | |
469 | |
470 b->last = (u_char *) ngx_escape_html(b->last, | |
471 entry[i].name.data, char_len); | |
472 last = b->last; | |
473 | |
474 } else { | |
475 b->last = ngx_cpystrn(b->last, entry[i].name.data, | |
476 NGX_HTTP_AUTOINDEX_NAME_LEN + 1); | |
477 last = b->last - 3; | |
478 } | |
450 } | 479 } |
451 | 480 |
452 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { | 481 if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { |
453 b->last = ngx_cpymem(last, "..></a>", sizeof("..></a>") - 1); | 482 b->last = ngx_cpymem(last, "..></a>", sizeof("..></a>") - 1); |
454 | 483 |