Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_image_filter_module.c @ 558:2da4537168f8 NGINX_0_8_31
nginx 0.8.31
*) Feature: now the "error_page" directive may redirect the 301 and 302
responses.
*) Feature: the $geoip_city_continent_code, $geoip_latitude, and
$geoip_longitude variables.
Thanks to Arvind Sundararajan.
*) Feature: now the ngx_http_image_filter_module deletes always EXIF
and other application specific data if the data consume more than 5%
of a JPEG file.
*) Bugfix: nginx closed a connection if a cached response had an empty
body.
Thanks to Piotr Sikora.
*) Bugfix: nginx might not be built by gcc 4.x if the -O2 or higher
optimization option was used.
Thanks to Maxim Dounin and Denis F. Latypoff.
*) Bugfix: regular expressions in location were always tested in
case-sensitive mode; the bug had appeared in 0.8.25.
*) Bugfix: nginx cached a 304 response if there was the "If-None-Match"
header line in a proxied request.
Thanks to Tim Dettrick and David Kostal.
*) Bugfix: nginx/Windows tried to delete a temporary file twice if the
file should replace an already existent file.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 23 Dec 2009 00:00:00 +0300 |
parents | 005a70f9573b |
children | 8246d8a2c2be |
comparison
equal
deleted
inserted
replaced
557:72104cd120ec | 558:2da4537168f8 |
---|---|
61 ngx_uint_t max_width; | 61 ngx_uint_t max_width; |
62 ngx_uint_t max_height; | 62 ngx_uint_t max_height; |
63 | 63 |
64 ngx_uint_t phase; | 64 ngx_uint_t phase; |
65 ngx_uint_t type; | 65 ngx_uint_t type; |
66 ngx_uint_t force; | |
66 } ngx_http_image_filter_ctx_t; | 67 } ngx_http_image_filter_ctx_t; |
67 | 68 |
68 | 69 |
69 static ngx_int_t ngx_http_image_send(ngx_http_request_t *r, | 70 static ngx_int_t ngx_http_image_send(ngx_http_request_t *r, |
70 ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in); | 71 ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in); |
499 return NULL; | 500 return NULL; |
500 } | 501 } |
501 | 502 |
502 if (rc == NGX_OK | 503 if (rc == NGX_OK |
503 && ctx->width <= ctx->max_width | 504 && ctx->width <= ctx->max_width |
504 && ctx->height <= ctx->max_height) | 505 && ctx->height <= ctx->max_height |
506 && !ctx->force) | |
505 { | 507 { |
506 return ngx_http_image_asis(r, ctx); | 508 return ngx_http_image_asis(r, ctx); |
507 } | 509 } |
508 | 510 |
509 return ngx_http_image_resize(r, ctx); | 511 return ngx_http_image_resize(r, ctx); |
599 | 601 |
600 static ngx_int_t | 602 static ngx_int_t |
601 ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | 603 ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) |
602 { | 604 { |
603 u_char *p, *last; | 605 u_char *p, *last; |
606 size_t len, app; | |
604 ngx_uint_t width, height; | 607 ngx_uint_t width, height; |
605 | 608 |
606 p = ctx->image; | 609 p = ctx->image; |
607 | 610 |
608 switch (ctx->type) { | 611 switch (ctx->type) { |
609 | 612 |
610 case NGX_HTTP_IMAGE_JPEG: | 613 case NGX_HTTP_IMAGE_JPEG: |
611 | 614 |
612 p += 2; | 615 p += 2; |
613 last = ctx->image + ctx->length - 10; | 616 last = ctx->image + ctx->length - 10; |
617 width = 0; | |
618 height = 0; | |
619 app = 0; | |
614 | 620 |
615 while (p < last) { | 621 while (p < last) { |
616 | 622 |
617 if (p[0] == 0xff && p[1] != 0xff) { | 623 if (p[0] == 0xff && p[1] != 0xff) { |
618 | 624 |
619 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 625 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
620 "JPEG: %02xd %02xd", *p, *(p + 1)); | 626 "JPEG: %02xd %02xd", p[0], p[1]); |
621 | 627 |
622 p++; | 628 p++; |
623 | 629 |
624 if (*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3 | 630 if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3 |
625 || *p == 0xc9 || *p == 0xca || *p == 0xcb) | 631 || *p == 0xc9 || *p == 0xca || *p == 0xcb) |
632 && (width == 0 || height == 0)) | |
626 { | 633 { |
627 goto found; | 634 width = p[6] * 256 + p[7]; |
635 height = p[4] * 256 + p[5]; | |
628 } | 636 } |
629 | 637 |
630 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 638 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
631 "JPEG: %02xd %02xd", p[1], p[2]); | 639 "JPEG: %02xd %02xd", p[1], p[2]); |
632 | 640 |
633 p += p[1] * 256 + p[2]; | 641 len = p[1] * 256 + p[2]; |
642 | |
643 if (*p >= 0xe1 && *p <= 0xef) { | |
644 /* application data, e.g., EXIF, Adobe XMP, etc. */ | |
645 app += len; | |
646 } | |
647 | |
648 p += len; | |
634 | 649 |
635 continue; | 650 continue; |
636 } | 651 } |
637 | 652 |
638 p++; | 653 p++; |
639 } | 654 } |
640 | 655 |
641 return NGX_DECLINED; | 656 if (width == 0 || height == 0) { |
642 | 657 return NGX_DECLINED; |
643 found: | 658 } |
644 | 659 |
645 width = p[6] * 256 + p[7]; | 660 if (ctx->length / 20 < app) { |
646 height = p[4] * 256 + p[5]; | 661 /* force conversion if application data consume more than 5% */ |
662 ctx->force = 1; | |
663 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
664 "app data size: %uz", app); | |
665 } | |
647 | 666 |
648 break; | 667 break; |
649 | 668 |
650 case NGX_HTTP_IMAGE_GIF: | 669 case NGX_HTTP_IMAGE_GIF: |
651 | 670 |
706 sx = gdImageSX(src); | 725 sx = gdImageSX(src); |
707 sy = gdImageSY(src); | 726 sy = gdImageSY(src); |
708 | 727 |
709 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | 728 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
710 | 729 |
711 if ((ngx_uint_t) sx <= ctx->max_width | 730 if (!ctx->force |
731 && (ngx_uint_t) sx <= ctx->max_width | |
712 && (ngx_uint_t) sy <= ctx->max_height) | 732 && (ngx_uint_t) sy <= ctx->max_height) |
713 { | 733 { |
714 gdImageDestroy(src); | 734 gdImageDestroy(src); |
715 return ngx_http_image_asis(r, ctx); | 735 return ngx_http_image_asis(r, ctx); |
716 } | 736 } |