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("&gt;") - 2 381 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 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, "..&gt;</a>", sizeof("..&gt;</a>") - 1); 482 b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1);
454 483