diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2020-02-05 19:32:36 +1300 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2020-02-05 19:38:55 +1300 |
commit | f71cff5703173333ec01f0451d488b82be0dd5d7 (patch) | |
tree | 8e0addca32ae9610f2a0f87aced103a52b3fad21 | |
parent | 4a6c17913fc0da3aec896d1a8912dd8a501c32d0 (diff) | |
download | rack-f71cff5703173333ec01f0451d488b82be0dd5d7.tar.gz |
Sort encodings by server preference. Implements #1184.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/rack/utils.rb | 22 | ||||
-rw-r--r-- | test/spec_utils.rb | 1 |
3 files changed, 16 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eea265c..f60641f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ All notable changes to this project will be documented in this file. For info on - `Request#ssl?` is true for the `wss` scheme (secure websockets). ([@jeremyevans](https://github.com/jeremyevans)) - `Rack::HeaderHash` is memoized by default. ([#1549](https://github.com/rack/rack/pull/1549), [@ioquatix](https://github.com/ioquatix)) - `Rack::Directory` allow directory traversal inside root directory. ([#1417](https://github.com/rack/rack/pull/1417), [@ThomasSevestre](https://github.com/ThomasSevestre)) +- Sort encodings by server preference. ([#1184](https://github.com/rack/rack/pull/1184), [@ioquatix](https://github.com/ioquatix), [@wjordan](https://github.com/wjordan)) ### Removed diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 0fef215d..f033c900 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -174,17 +174,23 @@ module Rack def select_best_encoding(available_encodings, accept_encoding) # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - expanded_accept_encoding = - accept_encoding.each_with_object([]) do |(m, q), list| - if m == "*" - (available_encodings - accept_encoding.map(&:first)) - .each { |m2| list << [m2, q] } - else - list << [m, q] + expanded_accept_encoding = [] + + accept_encoding.each do |m, q| + preference = available_encodings.index(m) || available_encodings.size + + if m == "*" + (available_encodings - accept_encoding.map(&:first)).each do |m2| + expanded_accept_encoding << [m2, q, preference] end + else + expanded_accept_encoding << [m, q, preference] end + end - encoding_candidates = expanded_accept_encoding.sort_by { |_, q| -q }.map!(&:first) + encoding_candidates = expanded_accept_encoding + .sort_by { |_, q, p| [-q, p] } + .map!(&:first) unless encoding_candidates.include?("identity") encoding_candidates.push("identity") diff --git a/test/spec_utils.rb b/test/spec_utils.rb index e25070bc..9a2d29e6 100644 --- a/test/spec_utils.rb +++ b/test/spec_utils.rb @@ -444,6 +444,7 @@ describe Rack::Utils do helper.call(%w(compress gzip identity), [["compress", 1.0], ["gzip", 1.0]]).must_equal "compress" helper.call(%w(compress gzip identity), [["compress", 0.5], ["gzip", 1.0]]).must_equal "gzip" + helper.call(%w(compress gzip identity), [["gzip", 1.0], ["compress", 1.0]]).must_equal "compress" helper.call(%w(foo bar identity), []).must_equal "identity" helper.call(%w(foo bar identity), [["*", 1.0]]).must_equal "foo" |