Module: Webmachine::Decision::Conneg
- Included in:
- Flow
- Defined in:
- lib/webmachine/decision/conneg.rb
Overview
Contains methods concerned with Content Negotiation, specifically, choosing media types, encodings, character sets and languages.
Defined Under Namespace
Classes: MediaTypeList, PriorityList
Constant Summary collapse
- HAS_ENCODING =
Ruby 1.9 compat
defined?(::Encoding)
Instance Method Summary collapse
-
#choose_charset(provided, header) ⇒ Object
private
Given the ‘Accept-Charset’ header and provided charsets, chooses an appropriate charset.
-
#choose_encoding(provided, header) ⇒ Object
private
Given the ‘Accept-Encoding’ header and provided encodings, chooses an appropriate encoding.
-
#choose_language(provided, header) ⇒ Object
private
Given the ‘Accept-Language’ header and provided languages, chooses an appropriate language.
-
#choose_media_type(provided, header) ⇒ Object
private
Given the ‘Accept’ header and provided types, chooses an appropriate media type.
-
#do_choose(choices, header, default) ⇒ Object
private
Makes an conneg choice based what is accepted and what is provided.
-
#language_match(range, tag) ⇒ Object
private
Implements language-negotation matching as described in RFC2616, section 14.14.
Instance Method Details
#choose_charset(provided, header) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Given the ‘Accept-Charset’ header and provided charsets, chooses an appropriate charset.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/webmachine/decision/conneg.rb', line 44 def choose_charset(provided, header) if provided && !provided.empty? charsets = provided.map {|c| c.first } if charset = do_choose(charsets, header, HAS_ENCODING ? Encoding.default_external.name : kcode_charset) [CHARSET] = charset end else true end end |
#choose_encoding(provided, header) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Given the ‘Accept-Encoding’ header and provided encodings, chooses an appropriate encoding.
33 34 35 36 37 38 39 |
# File 'lib/webmachine/decision/conneg.rb', line 33 def choose_encoding(provided, header) encodings = provided.keys if encoding = do_choose(encodings, header, IDENTITY) response.headers[CONTENT_ENCODING] = encoding unless encoding == IDENTITY [CONTENT_ENCODING] = encoding end end |
#choose_language(provided, header) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Given the ‘Accept-Language’ header and provided languages, chooses an appropriate language.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/webmachine/decision/conneg.rb', line 58 def choose_language(provided, header) if provided && !provided.empty? requested = PriorityList.build(header.split(SPLIT_SEMI)) star_priority = requested.priority_of(STAR) any_ok = star_priority && star_priority > 0.0 accepted = requested.find do |priority, range| if priority == 0.0 provided.delete_if {|tag| language_match(range, tag) } false else provided.any? {|tag| language_match(range, tag) } end end chosen = if accepted provided.find {|tag| language_match(accepted.last, tag) } elsif any_ok provided.first end if chosen ['Language'] = chosen response.headers['Content-Language'] = chosen end else true end end |
#choose_media_type(provided, header) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Given the ‘Accept’ header and provided types, chooses an appropriate media type.
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/webmachine/decision/conneg.rb', line 16 def choose_media_type(provided, header) types = Array(header).map{|h| h.split(SPLIT_SEMI) }.flatten requested = MediaTypeList.build(types) provided = provided.map do |p| # normalize_provided MediaType.parse(p) end # choose_media_type1 chosen = nil requested.each do |_, requested_type| break if chosen = media_match(requested_type, provided) end chosen end |
#do_choose(choices, header, default) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Makes an conneg choice based what is accepted and what is provided.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/webmachine/decision/conneg.rb', line 100 def do_choose(choices, header, default) choices = choices.dup.map {|s| s.downcase } accepted = PriorityList.build(header.split(SPLIT_SEMI)) default_priority = accepted.priority_of(default) star_priority = accepted.priority_of(STAR) default_ok = (default_priority.nil? && star_priority != 0.0) || default_priority any_ok = star_priority && star_priority > 0.0 chosen = accepted.find do |priority, acceptable| if priority == 0.0 choices.delete(acceptable.downcase) false else choices.include?(acceptable.downcase) end end (chosen && chosen.last) || # Use the matching one (any_ok && choices.first) || # Or first if "*" (default_ok && choices.include?(default) && default) # Or default end |
#language_match(range, tag) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Implements language-negotation matching as described in RFC2616, section 14.14.
A language-range matches a language-tag if it exactly equals the tag, or if it exactly equals a prefix of the tag such that the first tag character following the prefix is “-”.
93 94 95 |
# File 'lib/webmachine/decision/conneg.rb', line 93 def language_match(range, tag) range.downcase == tag.downcase || tag =~ /^#{Regexp.escape(range)}\-/i end |