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 }