PageRenderTime 77ms CodeModel.GetById 13ms app.highlight 60ms RepoModel.GetById 2ms app.codeStats 0ms

/vendor/bundle/jruby/2.1/gems/rack-1.5.2/test/spec_deflater.rb

https://github.com/delowong/logstash
Ruby | 204 lines | 168 code | 35 blank | 1 comment | 4 complexity | 680f934fa360cb12e8df28b5cea2cbc7 MD5 | raw file
  1require 'stringio'
  2require 'time'  # for Time#httpdate
  3require 'rack/deflater'
  4require 'rack/lint'
  5require 'rack/mock'
  6require 'zlib'
  7
  8describe Rack::Deflater do
  9  def deflater(app)
 10    Rack::Lint.new Rack::Deflater.new(app)
 11  end
 12
 13  def build_response(status, body, accept_encoding, headers = {})
 14    body = [body]  if body.respond_to? :to_str
 15    app = lambda do |env|
 16      res = [status, {}, body]
 17      res[1]["Content-Type"] = "text/plain" unless res[0] == 304
 18      res
 19    end
 20    request = Rack::MockRequest.env_for("", headers.merge("HTTP_ACCEPT_ENCODING" => accept_encoding))
 21    response = deflater(app).call(request)
 22
 23    return response
 24  end
 25
 26  def inflate(buf)
 27    inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
 28    inflater.inflate(buf) << inflater.finish
 29  end
 30
 31  should "be able to deflate bodies that respond to each" do
 32    body = Object.new
 33    class << body; def each; yield("foo"); yield("bar"); end; end
 34
 35    response = build_response(200, body, "deflate")
 36
 37    response[0].should.equal(200)
 38    response[1].should.equal({
 39      "Content-Encoding" => "deflate",
 40      "Vary" => "Accept-Encoding",
 41      "Content-Type" => "text/plain"
 42    })
 43    buf = ''
 44    response[2].each { |part| buf << part }
 45    inflate(buf).should.equal("foobar")
 46  end
 47
 48  should "flush deflated chunks to the client as they become ready" do
 49    body = Object.new
 50    class << body; def each; yield("foo"); yield("bar"); end; end
 51
 52    response = build_response(200, body, "deflate")
 53
 54    response[0].should.equal(200)
 55    response[1].should.equal({
 56      "Content-Encoding" => "deflate",
 57      "Vary" => "Accept-Encoding",
 58      "Content-Type" => "text/plain"
 59    })
 60    buf = []
 61    inflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
 62    response[2].each { |part| buf << inflater.inflate(part) }
 63    buf << inflater.finish
 64    buf.delete_if { |part| part.empty? }
 65    buf.join.should.equal("foobar")
 66  end
 67
 68  # TODO: This is really just a special case of the above...
 69  should "be able to deflate String bodies" do
 70    response = build_response(200, "Hello world!", "deflate")
 71
 72    response[0].should.equal(200)
 73    response[1].should.equal({
 74      "Content-Encoding" => "deflate",
 75      "Vary" => "Accept-Encoding",
 76      "Content-Type" => "text/plain"
 77    })
 78    buf = ''
 79    response[2].each { |part| buf << part }
 80    inflate(buf).should.equal("Hello world!")
 81  end
 82
 83  should "be able to gzip bodies that respond to each" do
 84    body = Object.new
 85    class << body; def each; yield("foo"); yield("bar"); end; end
 86
 87    response = build_response(200, body, "gzip")
 88
 89    response[0].should.equal(200)
 90    response[1].should.equal({
 91      "Content-Encoding" => "gzip",
 92      "Vary" => "Accept-Encoding",
 93      "Content-Type" => "text/plain"
 94    })
 95
 96    buf = ''
 97    response[2].each { |part| buf << part }
 98    io = StringIO.new(buf)
 99    gz = Zlib::GzipReader.new(io)
100    gz.read.should.equal("foobar")
101    gz.close
102  end
103
104  should "flush gzipped chunks to the client as they become ready" do
105    body = Object.new
106    class << body; def each; yield("foo"); yield("bar"); end; end
107
108    response = build_response(200, body, "gzip")
109
110    response[0].should.equal(200)
111    response[1].should.equal({
112      "Content-Encoding" => "gzip",
113      "Vary" => "Accept-Encoding",
114      "Content-Type" => "text/plain"
115    })
116    buf = []
117    inflater = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
118    response[2].each { |part| buf << inflater.inflate(part) }
119    buf << inflater.finish
120    buf.delete_if { |part| part.empty? }
121    buf.join.should.equal("foobar")
122  end
123
124  should "be able to fallback to no deflation" do
125    response = build_response(200, "Hello world!", "superzip")
126
127    response[0].should.equal(200)
128    response[1].should.equal({ "Vary" => "Accept-Encoding", "Content-Type" => "text/plain" })
129    response[2].to_enum.to_a.should.equal(["Hello world!"])
130  end
131
132  should "be able to skip when there is no response entity body" do
133    response = build_response(304, [], "gzip")
134
135    response[0].should.equal(304)
136    response[1].should.equal({})
137    response[2].to_enum.to_a.should.equal([])
138  end
139
140  should "handle the lack of an acceptable encoding" do
141    response1 = build_response(200, "Hello world!", "identity;q=0", "PATH_INFO" => "/")
142    response1[0].should.equal(406)
143    response1[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "71"})
144    response1[2].to_enum.to_a.should.equal(["An acceptable encoding for the requested resource / could not be found."])
145
146    response2 = build_response(200, "Hello world!", "identity;q=0", "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/bar")
147    response2[0].should.equal(406)
148    response2[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "78"})
149    response2[2].to_enum.to_a.should.equal(["An acceptable encoding for the requested resource /foo/bar could not be found."])
150  end
151
152  should "handle gzip response with Last-Modified header" do
153    last_modified = Time.now.httpdate
154
155    app = lambda { |env| [200, { "Content-Type" => "text/plain", "Last-Modified" => last_modified }, ["Hello World!"]] }
156    request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
157    response = deflater(app).call(request)
158
159    response[0].should.equal(200)
160    response[1].should.equal({
161      "Content-Encoding" => "gzip",
162      "Vary" => "Accept-Encoding",
163      "Last-Modified" => last_modified,
164      "Content-Type" => "text/plain"
165    })
166
167    buf = ''
168    response[2].each { |part| buf << part }
169    io = StringIO.new(buf)
170    gz = Zlib::GzipReader.new(io)
171    gz.read.should.equal("Hello World!")
172    gz.close
173  end
174
175  should "do nothing when no-transform Cache-Control directive present" do
176    app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Cache-Control' => 'no-transform'}, ['Hello World!']] }
177    request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
178    response = deflater(app).call(request)
179
180    response[0].should.equal(200)
181    response[1].should.not.include "Content-Encoding"
182    response[2].to_enum.to_a.join.should.equal("Hello World!")
183  end
184
185  should "do nothing when Content-Encoding already present" do
186    app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'gzip'}, ['Hello World!']] }
187    request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
188    response = deflater(app).call(request)
189
190    response[0].should.equal(200)
191    response[2].to_enum.to_a.join.should.equal("Hello World!")
192  end
193
194  should "deflate when Content-Encoding is identity" do
195    app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Encoding' => 'identity'}, ['Hello World!']] }
196    request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "deflate")
197    response = deflater(app).call(request)
198
199    response[0].should.equal(200)
200    buf = ''
201    response[2].each { |part| buf << part }
202    inflate(buf).should.equal("Hello World!")
203  end
204end