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
end
def method_handled?(env)
!!(env['REQUEST_METHOD'] =~ /(POST|PUT)/)
end
def encoding_handled?(env)
['gzip', 'deflate'].include? env['HTTP_CONTENT_ENCODING']
end
def call(env)
if method_handled?(env) && encoding_handled?(env)
extracted = decode(env['rack.input'], env['HTTP_CONTENT_ENCODING'])
env.delete('HTTP_CONTENT_ENCODING')
env['CONTENT_LENGTH'] = extracted.bytesize
env['rack.input'] = StringIO.new(extracted)
end
status, headers, response = @app.call(env)
return [status, headers, response]
end
def decode(input, content_encoding)
case content_encoding
when 'gzip' then Zlib::GzipReader.new(input).read
when 'deflate' then Zlib::Inflate.inflate(input.read)
end
end
end
Owner

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"
Owner

relistan commented Jul 3, 2012

Thanks for adding that!

Can this be used in Rails 2?

Owner

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: https://gist.github.com/mbrictson/9106778

agbodike commented Dec 4, 2015

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

https://gist.github.com/mattbrictson/9106778

plentz commented Oct 25, 2016

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

this does not work with rails 5.

Owner

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