diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-11-30 16:26:20 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-11-30 16:26:20 -0800 |
commit | 27eb2d7ebd29239a5043a528c97c6dd218d03217 (patch) | |
tree | 7eb9ccc289cd78af10374c01fb80061f0abeeff3 /lib/metropolis/deflate.rb | |
parent | 03755186d6cb968d44d7eb04de3ed2d047180272 (diff) | |
download | metropolis-27eb2d7ebd29239a5043a528c97c6dd218d03217.tar.gz |
support pass-through :encoding for deflate and gzip
These allow serving pre-compressed data off disk and on-the-fly uncompressing for the few clients that do not accept compressed responses.
Diffstat (limited to 'lib/metropolis/deflate.rb')
-rw-r--r-- | lib/metropolis/deflate.rb | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/metropolis/deflate.rb b/lib/metropolis/deflate.rb new file mode 100644 index 0000000..d585b43 --- /dev/null +++ b/lib/metropolis/deflate.rb @@ -0,0 +1,45 @@ +# -*- encoding: binary -*- +require "zlib" + +# allows storing pre-deflated data on disk and serving it +# as-is for clients that accept that deflate encoding +module Metropolis::Deflate + def get(key, env) + status, headers, body = r = super + if 200 == status && /\bdeflate\b/ !~ env['HTTP_ACCEPT_ENCODING'] + inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS) + body[0] = "#{inflater.inflate(body[0])}#{inflater.finish}" + inflater.end + headers['Content-Length'] = body[0].size.to_s + headers.delete('Content-Encoding') + headers.delete('Vary') + end + r + end + + def put(key, env) + Wrapper.new(env) + super(key, env) + end + + def self.extended(obj) + obj.instance_eval do + @headers['Content-Encoding'] = 'deflate' + @headers['Vary'] = 'Accept-Encoding' + end + end + + class Wrapper < Metropolis::InputWrapper + + def read_all + deflater = Zlib::Deflate.new( + Zlib::DEFAULT_COMPRESSION, + # drop the zlib header which causes both Safari and IE to choke + -Zlib::MAX_WBITS, + Zlib::DEF_MEM_LEVEL, + Zlib::DEFAULT_STRATEGY + ) + "#{deflater.deflate(@input.read)}#{deflater.finish}" + end + end +end |