summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-02-05 19:32:36 +1300
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-02-05 19:38:55 +1300
commitf71cff5703173333ec01f0451d488b82be0dd5d7 (patch)
tree8e0addca32ae9610f2a0f87aced103a52b3fad21
parent4a6c17913fc0da3aec896d1a8912dd8a501c32d0 (diff)
downloadrack-f71cff5703173333ec01f0451d488b82be0dd5d7.tar.gz
Sort encodings by server preference. Implements #1184.
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/rack/utils.rb22
-rw-r--r--test/spec_utils.rb1
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"