Skip to content

HTTPS clone URL

Subversion checkout URL

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