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
@relistan

This comment has been minimized.

Show comment Hide comment
@relistan

relistan 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.

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.

@adamonduty

This comment has been minimized.

Show comment Hide comment
@adamonduty

adamonduty Apr 13, 2012

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

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

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

This comment has been minimized.

Show comment Hide comment
@relistan

relistan Jul 3, 2012

Thanks for adding that!

Owner

relistan commented Jul 3, 2012

Thanks for adding that!

@asyncrecruiting

This comment has been minimized.

Show comment Hide comment
@asyncrecruiting

asyncrecruiting May 23, 2013

Can this be used in Rails 2?

Can this be used in Rails 2?

@relistan

This comment has been minimized.

Show comment Hide comment
@relistan

relistan Jul 16, 2013

Sorry to miss this question. It should be usable on anything that supports standard Rack middleware, including 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.

@mattbrictson

This comment has been minimized.

Show comment Hide comment
@mattbrictson

mattbrictson Feb 11, 2014

Thanks for this gist! It’s working great.

Thanks for this gist! It’s working great.

@mattbrictson

This comment has been minimized.

Show comment Hide comment
@mattbrictson

mattbrictson Feb 20, 2014

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

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

This comment has been minimized.

Show comment Hide comment
@agbodike

agbodike Dec 4, 2015

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

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

This comment has been minimized.

Show comment Hide comment
@plentz

plentz Oct 25, 2016

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

this does not work with rails 5.

plentz commented Oct 25, 2016

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

this does not work with rails 5.

@relistan

This comment has been minimized.

Show comment Hide comment
@relistan

relistan 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.

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