diff --git a/lib/response_bank.rb b/lib/response_bank.rb index 1c334bf..c8934b7 100644 --- a/lib/response_bank.rb +++ b/lib/response_bank.rb @@ -33,7 +33,20 @@ def read_from_backing_cache_store(_env, cache_key, backing_cache_store: cache_st def compress(content, encoding = "br") case encoding when 'gzip' - Zlib.gzip(content, level: Zlib::BEST_COMPRESSION) + attempts = 0 + + begin + Zlib.gzip(content, level: Zlib::BEST_COMPRESSION) + rescue Zlib::BufError + # We get sporadic Zlib::BufError, so we retry once (https://github.com/ruby/zlib/issues/49) + attempts += 1 + + if attempts <= 1 + retry + else + raise + end + end when 'br' Brotli.deflate(content, mode: :text, quality: 7) else diff --git a/test/response_bank_test.rb b/test/response_bank_test.rb index e312a4c..945367f 100644 --- a/test/response_bank_test.rb +++ b/test/response_bank_test.rb @@ -67,4 +67,20 @@ def test_cache_key_for_datetime def test_cache_key_for_date assert_equal("2020-01-01", ResponseBank.cache_key_for(Date.new(2020, 1, 1))) end + + def test_compress_retries_once_on_zlib_buferror + content = 'mycontent' + compressed_content = Zlib.gzip(content, level: Zlib::BEST_COMPRESSION) + Zlib.stubs(:gzip).raises(Zlib::BufError).then.returns(compressed_content) + + assert_equal(compressed_content, ResponseBank.compress(content, "gzip")) + end + + def test_compress_retries_once_on_zlib_buferror_and_raises_if_it_happens_again + Zlib.stubs(:gzip).raises(Zlib::BufError) + + assert_raises(Zlib::BufError) do + ResponseBank.compress("mycontent", "gzip") + end + end end diff --git a/test/response_cache_handler_test.rb b/test/response_cache_handler_test.rb index 4062277..b4f0b13 100644 --- a/test/response_cache_handler_test.rb +++ b/test/response_cache_handler_test.rb @@ -125,7 +125,7 @@ def test_server_cache_hit_but_empty_body _status, _headers, _body, _timestamp = empty_page ResponseBank.expects(:decompress).never - status, headers, body = handler.run! + status, headers, _body = handler.run! assert_equal(_status, status) assert_equal(_headers['Content-Type'], headers["Content-Type"]) @@ -143,7 +143,7 @@ def test_server_cache_hit_support_gzip ResponseBank.expects(:decompress).returns(_body).once - status, headers, body = handler.run! + status, headers, _body = handler.run! assert_equal(_status, status) assert_equal(_headers['Content-Type'], headers["Content-Type"])