Gzipping proxied content after using subs_filter fails

As the title says, I’m having an issue with gzipping proxied web pages
after using subs_filter. It doesn’t always happen, but it looks like
whenever a page exceeds the size of one of my proxy_buffers I get an
error in the error log saying:

[alert] 18544#0: *490084 deflate() failed: 2, -5 while sending to
client, client: xxx.xxx.xxx.xxx, server: www.test.com, request: “GET /
HTTP/1.1”, upstream: “http://xxx.xxx.xxx.xxx:80/”, host: “www.test.com”,
referrer: “http://xxx.xxx.xxx.xxx/

The page, without any compression, is roughly 80k. When I boost my
proxy_buffers to 100k the page loads fine. When it is below the 80k of
the page, I only receive a partial version of the page (roughly 5k,
whether proxy_buffer_size is set to 4k or 8k).

Turning off gzip serves the entire page as does disabling the
subs_filter commands.

Is there any workaround/fix for this outside of just boosting the
proxy_buffers value so that it exceeds every possible text/html page I’m
serving?

In case they’re helpful, my normal proxy and gzip settings are:

proxy_cache_use_stale updating error timeout invalid_header http_500
http_502 http_504;
proxy_cache_valid 60m;
proxy_redirect off;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffers 8 16k;
proxy_buffer_size 16k;
proxy_busy_buffers_size 64k;
proxy_cache_key $host$request_uri$is_args$args;

gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 8;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript
text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;
gzip_disable “MSIE [1-6].(?!.*SV1)”;

Thanks!

Posted at Nginx Forum:

Hello!

On Thu, Aug 09, 2012 at 05:28:06PM -0400, abstein2 wrote:

As the title says, I’m having an issue with gzipping proxied web pages
after using subs_filter. It doesn’t always happen, but it looks like
whenever a page exceeds the size of one of my proxy_buffers I get an
error in the error log saying:

[alert] 18544#0: *490084 deflate() failed: 2, -5 while sending to
client, client: xxx.xxx.xxx.xxx, server: www.test.com, request: “GET /
HTTP/1.1”, upstream: “http://xxx.xxx.xxx.xxx:80/”, host: “www.test.com”,
referrer: “http://xxx.xxx.xxx.xxx/

Here nginx did deflate with Z_SYNC_FLUSH (2) and deflate()
returned error Z_BUF_ERROR (-5, no progress possible). The error
message suggests you are using an old nginx, and subs filter
somehow triggers the problem as fixed here:

http://trac.nginx.org/nginx/changeset/4469/nginx

Changes with nginx 1.1.15:

*) Bugfix: calling $r->flush() multiple times might cause errors in 

the
ngx_http_gzip_filter_module.

It’s not clear why subs filter triggers flush (and does so twice in a
row),
most likely it’s a bug in subs filter (you may want to ask it’s author),
but
upgrading nginx to 1.1.15+ should resolve the problem.

[…]

Maxim D.

Hi,

Can you try the latest code from github:
GitHub - yaoweibin/ngx_http_substitutions_filter_module: a filter module which can do both regular expression and fixed string substitutions for nginx?

I’m just refactoring this module. And I want to add more verification
with the flush buffer. There may be bugs with the old version.

Thanks for your report.

2012/8/10 Maxim D. [email protected]:

Thanks. I’ll check this problem tonight. Can you send me your
nginx.conf and the test page?

You can sent it to my private email: [email protected]

2012/8/13 abstein2 [email protected]:

It is a great chance for all the pc game fans for that the Guild Wars 2
is coming on the way! We could freely enjoy the game after it is
released on August 28. Now, I have found a good place
tobuy guild wars 2 gold,
the gw2 gold in this store is cheaper than any
othergw2 gold store. If
youwant to buy cheap guild wars 2 gold. I think it is an idea choice! I
ama old fan for guild wars and I do hopely the guild wars 2 can
comesoon!

Posted at Nginx Forum:

It looks like there’s an issue with the newest revision of the module
and nginx 1.2.3. When installed, whether gzip is on or off, the portion
of code that was previously missing/not transmitted now gets
transmitted, but isn’t the actual page content. Instead it’s gibberish
with some of the raw nginx configuration mixed in.

An example of the code being output:

Xv±t™Xv±t™ ý ý w.google-analytics.com/urchin.js"
type=“text/javascript”> ct.asp">CONTACT US | PRIVACY POLICY | TERMS OF
USE
ccel-expiresx-accel-charsetx-accel-redirectstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirect¨Æ½/usr/scgi_temp@ǽ€Ç½ÀǽȽ@Ƚstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectɽ/usr/scgi_tempÀɽʽ@ʽ€Ê½Àʽstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirecth˽/usr/scgi_temp̽@̽€Ì½À̽ͽstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectÈͽ/usr/scgi_temp€Î½ÀνϽ@Ͻ€Ï½statusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirect(н/usr/scgi_tempÀнѽ@ѽ€Ñ½Àѽstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectˆÒ½/usr/scgi_temp@Ó½€Ó½ÀÓ½Ô½@Ô½statusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectèÔ½/usr/scgi_temp€Õ½ÀÕ½Ö½@Ö½€Ö½statusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectH×½/usr/scgi_tempؽ@ؽ€Ø½Àؽٽstatusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirect¨Ù½/usr/scgi_temp@Ú½€Ú½ÀÚ½Û½@Û½statusx-accel-bufferingx-accel-limit-ratex-accel-expiresx-accel-charsetx-accel-redirectܽ

The actual HTML code does show up after a block of text like the one
above, but it begins mid-string as though it must be a completely new
chunk in the buffer. All subs_filter replacements have already occurred
by the time it reaches the gibberish block.

Using 1.2.1 along with an older version of the module seems to work
properly as Maxim had suggested. I’m happy to help continue to test this
in any way possible.

Posted at Nginx Forum:

I have e-mailed Yao Weibin, but wanted to give an update here regarding
my findings. It appears the issue is linked to long strings of text
unbroken by a new line. With my settings, it appears that if a line
contains ~40k bytes without being broken by a new line, something occurs
whether gzip is on or off, that causes the gibberish to appear on the
page.

Thank you all for your input so far.

Posted at Nginx Forum:

Thanks. This bug is fixed in the latest revision
(GitHub - yaoweibin/ngx_http_substitutions_filter_module: a filter module which can do both regular expression and fixed string substitutions for nginx)

2012/8/14 abstein2 [email protected]: