From 57d05a8eacf46171d3c9a88a1305a7e830215d2e Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Mon, 10 Aug 2026 12:16:15 +1200 Subject: [PATCH] Add stable Accept preference ordering. --- lib/protocol/http/header/accept.rb | 11 +++++++++++ releases.md | 4 ++++ test/protocol/http/header/accept.rb | 4 ++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/protocol/http/header/accept.rb b/lib/protocol/http/header/accept.rb index bbad9ff..4a02b91 100644 --- a/lib/protocol/http/header/accept.rb +++ b/lib/protocol/http/header/accept.rb @@ -107,6 +107,17 @@ def media_ranges end end + # Parse the `accept` header and order media ranges by preference. + # + # Media ranges with equal quality factors retain their original relative order. + # + # @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 + end + private def parse_media_range(value) diff --git a/releases.md b/releases.md index 01bc95c..17417b9 100644 --- a/releases.md +++ b/releases.md @@ -1,5 +1,9 @@ # Releases +## Unreleased + + - Add stable preference ordering for `Accept` media ranges. + ## v0.69.0 - Add `Protocol::HTTP::Body::Readable#to_io` for obtaining an IO-compatible stream adapter. diff --git a/test/protocol/http/header/accept.rb b/test/protocol/http/header/accept.rb index 2c09b0a..d9f878e 100644 --- a/test/protocol/http/header/accept.rb +++ b/test/protocol/http/header/accept.rb @@ -21,7 +21,7 @@ describe Protocol::HTTP::Header::Accept do let(:header) {subject.parse(description)} - let(:media_ranges) {header.media_ranges.sort} + let(:media_ranges) {header.preferred_media_ranges} with "text/plain, text/html;q=0.5, text/xml;q=0.25" do it "can parse media ranges" do @@ -64,7 +64,7 @@ end with "text/html, text/plain;q=0.8, text/xml;q=0.6, application/json" do - it "should order based on quality factor" do + it "preserves relative order for equal quality factors" do expect(media_ranges.collect(&:to_s)).to be == %w{text/html application/json text/plain;q=0.8 text/xml;q=0.6} end end