Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 89 lines (72 sloc) 2.25 kB
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
1 require "zlib"
cabc20d added gzip support to Rack::Deflater
Ben authored
2 require "stringio"
e44d908 Fixed Rack::Deflater to handle responses with Last-Modified header
Dan Kubb authored
3 require "time" # for Time.httpdate
d6fa6af @josh Explicitly require request, response, and utils
josh authored
4 require 'rack/utils'
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
5
6 module Rack
7
8 class Deflater
9 def initialize(app)
10 @app = app
11 end
12
13 def call(env)
14 status, headers, body = @app.call(env)
76c3aef @rtomayko Use HeaderHash where header case should be insensitive
rtomayko authored
15 headers = Utils::HeaderHash.new(headers)
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
16
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
17 # Skip compressing empty entity body responses and responses with
18 # no-transform set.
76c3aef @rtomayko Use HeaderHash where header case should be insensitive
rtomayko authored
19 if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
20 headers['Cache-Control'].to_s =~ /\bno-transform\b/
c868880 Do not add Content-Encoding for a response without and entity body
Dan Kubb authored
21 return [status, headers, body]
22 end
23
a2157d0 @qerub deflater.rb - Removed unnecessary require "time" and whitespace
qerub authored
24 request = Request.new(env)
6967688 @qerub deflater.rb - Added an error message for the 406 Not Acceptable case
qerub authored
25
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
26 encoding = Utils.select_best_encoding(%w(gzip deflate identity),
27 request.accept_encoding)
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
28
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
29 # Set the Vary HTTP header.
3b11658 Added Accept-Encoding to HTTP Vary header
Dan Kubb authored
30 vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
31 unless vary.include?("*") || vary.include?("Accept-Encoding")
32 headers["Vary"] = vary.push("Accept-Encoding").join(",")
33 end
34
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
35 case encoding
cabc20d added gzip support to Rack::Deflater
Ben authored
36 when "gzip"
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
37 mtime = if headers.key?("Last-Modified")
38 Time.httpdate(headers["Last-Modified"])
39 else
40 Time.now
41 end
42 [status,
43 headers.merge("Content-Encoding" => "gzip"),
44 self.class.gzip(body, mtime)]
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
45 when "deflate"
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
46 [status,
47 headers.merge("Content-Encoding" => "deflate"),
48 self.class.deflate(body)]
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
49 when "identity"
50 [status, headers, body]
51 when nil
48bbf3f @chneukirchen Reformat Rack::Deflater code
chneukirchen authored
52 message = ["An acceptable encoding for the requested resource #{request.fullpath} could not be found."]
6967688 @qerub deflater.rb - Added an error message for the 406 Not Acceptable case
qerub authored
53 [406, {"Content-Type" => "text/plain"}, message]
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
54 end
55 end
56
fd8b436 @qerub deflater.rb - Make gzip's mtime parameter mandatory
qerub authored
57 def self.gzip(body, mtime)
cabc20d added gzip support to Rack::Deflater
Ben authored
58 io = StringIO.new
59 gzip = Zlib::GzipWriter.new(io)
d2d51ff @spicyj added mtime for Deflater.gzip and fixed gzip spec
spicyj authored
60 gzip.mtime = mtime
cabc20d added gzip support to Rack::Deflater
Ben authored
61
62 # TODO: Add streaming
63 body.each { |part| gzip << part }
64
65 gzip.close
66 return io.string
67 end
68
f3b542a @qerub deflater.rb - Move out the Zlib::Deflate constructor arguments to a c…
qerub authored
69 DEFLATE_ARGS = [
70 Zlib::DEFAULT_COMPRESSION,
71 # drop the zlib header which causes both Safari and IE to choke
72 -Zlib::MAX_WBITS,
73 Zlib::DEF_MEM_LEVEL,
74 Zlib::DEFAULT_STRATEGY
75 ]
76
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
77 # Loosely based on Mongrel's Deflate handler
78 def self.deflate(body)
f3b542a @qerub deflater.rb - Move out the Zlib::Deflate constructor arguments to a c…
qerub authored
79 deflater = Zlib::Deflate.new(*DEFLATE_ARGS)
a31ee95 @qerub Implemented Rack::Deflater
qerub authored
80
81 # TODO: Add streaming
82 body.each { |part| deflater << part }
83
84 return deflater.finish
85 end
86 end
87
88 end
Something went wrong with that request. Please try again.