Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Rack Middleware to automatically unzip gzipped/deflated POST data
class CompressedRequests
def initialize(app)
@app = app
def method_handled?(env)
!!(env['REQUEST_METHOD'] =~ /(POST|PUT)/)
def encoding_handled?(env)
['gzip', 'deflate'].include? env['HTTP_CONTENT_ENCODING']
def call(env)
if method_handled?(env) && encoding_handled?(env)
extracted = decode(env['rack.input'], env['HTTP_CONTENT_ENCODING'])
env['CONTENT_LENGTH'] = extracted.bytesize
env['rack.input'] =
status, headers, response =
return [status, headers, response]
def decode(input, content_encoding)
case content_encoding
when 'gzip' then
when 'deflate' then Zlib::Inflate.inflate(

relistan commented Mar 21, 2012

Rack Middleware to Handle gzip and deflate Content Encodings

This fork has been simplified, clarified and for the common case (gzip) will reduce by one the number of times a StringIO is created and populated with the request body. Also fixes a bug where it would try to handle any content-encoding even though it can only handle two of them. Thanks to subdigital for the original.

Awesome! To get this to work with Rails 3, I had to insert it before ActionDispatch::ParamsParser:

config.middleware.insert_before ActionDispatch::ParamsParser, "CompressedRequests"

relistan commented Jul 3, 2012

Thanks for adding that!

Can this be used in Rails 2?


relistan commented Jul 16, 2013

Sorry to miss this question. It should be usable on anything that supports standard Rack middleware, including Rails 2.

Thanks for this gist! It’s working great.

I found that for a payload that uses multibyte strings, the content length was not getting set correctly. The solution is to use .bytesize instead of .length.

env['CONTENT_LENGTH'] = extracted.bytesize

Here's my fork with the fix:

agbodike commented Dec 4, 2015

It looks like the account name above moved, the updated location is:

plentz commented Oct 25, 2016

config.middleware.insert_before ActionDispatch::ParamsParser, "CompressedRequests"

this does not work with rails 5.


relistan commented Dec 28, 2016

This is fixed for the CONTENT_LENGTH issue now. I don't know Rails 5 @plentz, so if you knew what needs to go there instead, please post that here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment