Class: Doze::Negotiator
- Inherits:
-
Object
- Object
- Doze::Negotiator
- Defined in:
- lib/doze/negotiator.rb
Overview
A Negotiator handles content negotiation on behalf of a client request. It will choose the entity it prefers from a list of options offered to it. You can ask it to give you a quality value, or to choose from a list of options. It’ll choose from media_types, languages, or combinations of the two.
Instance Method Summary collapse
-
#choose_entity(entities) ⇒ Object
Choose from a list of Doze::Entity.
-
#initialize(request, ignore_unacceptable_accepts = false) ⇒ Negotiator
constructor
A new instance of Negotiator.
- #language_quality(language) ⇒ Object
- #media_type_quality(media_type) ⇒ Object
-
#quality(media_type, language) ⇒ Object
Combined quality value for a (media_type, language) pair.
Constructor Details
#initialize(request, ignore_unacceptable_accepts = false) ⇒ Negotiator
Returns a new instance of Negotiator.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/doze/negotiator.rb', line 6 def initialize(request, ignore_unacceptable_accepts=false) @ignore_unacceptable_accepts = ignore_unacceptable_accepts @media_type_criterea = if (ext = request.extension) # if the request extension requests a specific media type, this overrides any Accept header and is # interpreted as a demand for this media type and this one only. media_type = Doze::MediaType::BY_EXTENSION[ext] if media_type [[media_type.name, 2, 1.0]] else # if there's a request extension but we can't find a media type for it, we interpret this as an # 'impossible demand' that will match nothing [] end elsif (accept_header = request.env['HTTP_ACCEPT']) parse_accept_header(accept_header) {|range| matcher_from_media_range(range)}.sort_by {|matcher,specificity,q| -specificity} else # No Accept header - anything will do [[Object, 0, 1.0]] end accept_language_header = request.env['HTTP_ACCEPT_LANGUAGE'] @language_criterea = if accept_language_header parse_accept_header(accept_language_header) {|range| matcher_from_language_range(range)}.sort_by {|matcher,specificity,q| -specificity} + [[nil, 0, 0.001]] # When language_criterea are given, we allow a low-specificity tiny-but-nonzero match for a language of 'nil', ie entities with no # language, even though the accept header may appear to require a particular language. Because it makes no sense to apply Accept-Language # criterea to resources whose representations aren't language-specific. else [[Object, 0, 1.0]] end end |
Instance Method Details
#choose_entity(entities) ⇒ Object
Choose from a list of Doze::Entity
54 55 56 |
# File 'lib/doze/negotiator.rb', line 54 def choose_entity(entities) max_by_non_zero(entities) {|a| quality(a.media_type, a.language)} end |
#language_quality(language) ⇒ Object
44 45 46 |
# File 'lib/doze/negotiator.rb', line 44 def language_quality(language) @language_criterea.each {|matcher,specificity,quality| return quality if matcher === language}; 0 end |
#media_type_quality(media_type) ⇒ Object
40 41 42 |
# File 'lib/doze/negotiator.rb', line 40 def media_type_quality(media_type) @media_type_criterea.each {|matcher,specificity,quality| return quality if media_type.matches_names.any? {|name| matcher === name}}; 0 end |
#quality(media_type, language) ⇒ Object
Combined quality value for a (media_type, language) pair
49 50 51 |
# File 'lib/doze/negotiator.rb', line 49 def quality(media_type, language) media_type_quality(media_type)*language_quality(language) end |