Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/protocol/http/header/accept.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ def media_ranges
#
# @returns [Array(MediaRange)] the preferred media ranges.
def preferred_media_ranges
media_ranges.sort_by.with_index do |media_range, index|
[-media_range.quality_factor, index]
end
sort_by_quality_factor(media_ranges)
end

private
Expand Down
9 changes: 9 additions & 0 deletions lib/protocol/http/header/accept_charset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ def charsets
end
end
end

# Parse the `accept-charset` header and order character sets by preference.
#
# Character sets with equal quality factors retain their original relative order.
#
# @returns [Array(Charset)] the preferred character sets.
def preferred_charsets
sort_by_quality_factor(charsets)
end
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions lib/protocol/http/header/accept_encoding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ def encodings
end
end
end

# Parse the `accept-encoding` header and order encodings by preference.
#
# Encodings with equal quality factors retain their original relative order.
#
# @returns [Array(Encoding)] the preferred encodings.
def preferred_encodings
sort_by_quality_factor(encodings)
end
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions lib/protocol/http/header/accept_language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ def languages
end
end
end

# Parse the `accept-language` header and order languages by preference.
#
# Languages with equal quality factors retain their original relative order.
#
# @returns [Array(Language)] the preferred languages.
def preferred_languages
sort_by_quality_factor(languages)
end
end
end
end
Expand Down
8 changes: 8 additions & 0 deletions lib/protocol/http/header/split.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ def self.trailer?
end

protected
# Order weighted values by descending quality while preserving their relative order.
# @parameter values [Enumerable] The values which respond to `#quality_factor`.
# @returns [Array] The ordered values.
def sort_by_quality_factor(values)
values.sort_by.with_index do |value, index|
[-value.quality_factor, index]
end
end

def reverse_find(&block)
reverse_each do |value|
Expand Down
9 changes: 9 additions & 0 deletions lib/protocol/http/header/te.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ def transfer_codings
end
end

# Parse the `te` header and order transfer codings by preference.
#
# Transfer codings with equal quality factors retain their original relative order.
#
# @returns [Array(TransferCoding)] the preferred transfer codings.
def preferred_transfer_codings
sort_by_quality_factor(transfer_codings)
end

# @returns [Boolean] whether the `chunked` encoding is accepted.
def chunked?
self.any?{|value| value.start_with?(CHUNKED)}
Expand Down
2 changes: 1 addition & 1 deletion releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

- Add stable preference ordering for `Accept` media ranges.
- Add stable preference ordering for weighted `Accept`, `Accept-Charset`, `Accept-Encoding`, `Accept-Language`, and `TE` values.

## v0.69.0

Expand Down
2 changes: 1 addition & 1 deletion test/protocol/http/header/accept_charset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

describe Protocol::HTTP::Header::AcceptCharset do
let(:header) {subject.parse(description)}
let(:charsets) {header.charsets.sort}
let(:charsets) {header.preferred_charsets}

with "utf-8, iso-8859-1;q=0.5, windows-1252;q=0.25" do
it "can parse charsets" do
Expand Down
2 changes: 1 addition & 1 deletion test/protocol/http/header/accept_encoding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

describe Protocol::HTTP::Header::AcceptEncoding do
let(:header) {subject.parse(description)}
let(:encodings) {header.encodings.sort}
let(:encodings) {header.preferred_encodings}

with "gzip, deflate;q=0.5, identity;q=0.25" do
it "can parse charsets" do
Expand Down
2 changes: 1 addition & 1 deletion test/protocol/http/header/accept_language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

describe Protocol::HTTP::Header::AcceptLanguage do
let(:header) {subject.parse(description)}
let(:languages) {header.languages.sort}
let(:languages) {header.preferred_languages}

with "da, en-gb;q=0.5, en;q=0.25" do
it "can parse languages" do
Expand Down
9 changes: 8 additions & 1 deletion test/protocol/http/header/te.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@

with "gzip;q=0.5, deflate;q=0.8" do
it "handles multiple quality factors" do
codings = header.transfer_codings.sort
codings = header.preferred_transfer_codings
expect(codings[0].name).to be == "deflate" # higher quality first
expect(codings[1].name).to be == "gzip"
end
end

with "gzip, deflate;q=0.5, compress;q=0.5" do
it "preserves relative order for equal quality factors" do
codings = header.preferred_transfer_codings
expect(codings.collect(&:name)).to be == %w{gzip deflate compress}
end
end

with "empty header value" do
let(:header) {subject.new}

Expand Down
Loading