The mixin that adds methods to Strelka::HTTPRequest for content-negotiation.
request.accepts?( 'application/json' ) request.explicitly_accepts?( 'application/xml+rdf' ) request.accepts_charset?( Encoding::UTF_8 ) request.accepts_charset?( 'iso-8859-15' ) request.accepts_encoding?( 'compress' ) request.accepts_language?( 'en' ) request.explicitly_accepts_language?( 'en' ) request.explicitly_accepts_language?( 'en-gb' )
Extension callback – add instance variables to extended objects.
# File lib/strelka/httprequest/negotiation.rb, line 24
def initialize( * )
super
@accepted_mediatypes = nil
@accepted_charsets = nil
@accepted_encodings = nil
@accepted_languages = nil
end
Fetch the value of the given header
, split apart the values,
and parse each one using the specified paramclass
. If no
values are parsed from the header, and a block is given, the block is
called and its return value is appended to the empty Array before returning
it.
# File lib/strelka/httprequest/negotiation.rb, line 37
def parse_negotiation_header( header, paramclass )
self.log.debug "Parsing %s header into %p objects" % [ header, paramclass ]
rval = []
headerval = self.headers[ header ]
self.log.debug " raw header value: %p" % [ headerval ]
# Handle the case where there's more than one of the header in question by
# forcing everything to an Array
Array( headerval ).compact.flatten.each do |paramstr|
paramstr.split( /\s*,\s*/ ).each do |param|
self.log.debug " parsing param: %p" % [ param ]
rval << paramclass.parse( param )
end
end
if rval.empty? && block_given?
self.log.debug " no parsed values; calling the fallback block"
rval << yield
end
return rval.flatten
end
Return an Array of Strelka::HTTPRequest::Charset objects for each type in the 'Accept-Charset' header.
# File lib/strelka/httprequest/negotiation.rb, line 113
def accepted_charsets
@accepted_charsets ||= self.parse_accept_charset_header
return @accepted_charsets
end
Returns boolean true/false if the requestor can handle the given
charset
.
# File lib/strelka/httprequest/negotiation.rb, line 121
def accepts_charset?( charset )
self.log.debug "Checking to see if request accepts charset: %p" % [ charset ]
aset = self.accepted_charsets.find {|cs| cs =~ charset }
self.log.debug " find returned: %p" % [ aset ]
return aset ? true : false
end
Returns boolean true/false if the requestor can handle the given
charset
, not including the wildcard tag if present.
# File lib/strelka/httprequest/negotiation.rb, line 132
def explicitly_accepts_charset?( charset )
non_wildcard_charsets = self.accepted_charsets.reject {|param| param.charset.nil? }
return non_wildcard_charsets.find {|cs| cs =~ charset } ? true : false
end
Parse the receiver's 'Accept-Charset' header and return it as an Array of Strelka::HTTPRequest::Charset objects.
# File lib/strelka/httprequest/negotiation.rb, line 141
def parse_accept_charset_header
return self.parse_negotiation_header( :accept_charset, Strelka::HTTPRequest::Charset ) do
Strelka::HTTPRequest::Charset.new( '*' )
end
end
Return an Array of Strelka::HTTPRequest::Encoding objects for each type in the 'Accept-Encoding' header.
# File lib/strelka/httprequest/negotiation.rb, line 154
def accepted_encodings
@accepted_encodings ||= self.parse_accept_encoding_header
return @accepted_encodings
end
Returns boolean true/false if the requestor can handle the given
encoding
.
# File lib/strelka/httprequest/negotiation.rb, line 162
def accepts_encoding?( encoding )
self.log.debug "Checking to see if request accepts encoding: %p" % [ encoding ]
return true if self.accepted_encodings.empty?
found_encoding = self.accepted_encodings.find {|enc| enc =~ encoding }
self.log.debug " find returned: %p" % [ found_encoding ]
# If there was no match, then it's not accepted, unless it's the 'identity'
# encoding, which is accepted unless it's disabled.
return encoding == 'identity' if !found_encoding
return found_encoding.qvalue.nonzero?
end
Returns boolean true/false if the requestor can handle the given
encoding
, not including the wildcard encoding if present.
# File lib/strelka/httprequest/negotiation.rb, line 179
def explicitly_accepts_encoding?( encoding )
non_wildcard_encodings = self.accepted_encodings.reject {|enc| enc.content_coding.nil? }
found_encoding = non_wildcard_encodings.find {|enc| enc =~ encoding } or
return false
return found_encoding.qvalue.nonzero?
end
Parse the receiver's 'Accept-Encoding' header and return it as an Array of Strelka::HTTPRequest::Encoding objects.
# File lib/strelka/httprequest/negotiation.rb, line 190
def parse_accept_encoding_header
return self.parse_negotiation_header( :accept_encoding, Strelka::HTTPRequest::Encoding ) do
# If the Accept-Encoding field-value is empty, then only the "identity"
# encoding is acceptable.
if self.headers.include?( :accept_encoding )
self.log.debug "Empty accept-encoding header: identity-only"
[ Strelka::HTTPRequest::Encoding.new('identity') ]
# I have no idea how this is different than an empty accept-encoding header
# for any practical case, but RFC2616 says:
# If no Accept-Encoding field is present in a request, the server MAY
# assume that the client will accept any content coding. In this
# case, if "identity" is one of the available content-codings, then
# the server SHOULD use the "identity" content-coding, unless it has
# additional information that a different content-coding is meaningful
# to the client.
else
self.log.debug "No accept-encoding header: identity + any encoding"
[
Strelka::HTTPRequest::Encoding.new( 'identity' ),
Strelka::HTTPRequest::Encoding.new( '*', nil, 0.9 )
]
end
end
end
Return an Array of Strelka::HTTPRequest::Language objects for each type in the 'Accept-Language' header.
# File lib/strelka/httprequest/negotiation.rb, line 224
def accepted_languages
@accepted_languages ||= self.parse_accept_language_header
return @accepted_languages
end
Returns boolean true/false if the requestor can handle the given
language
.
# File lib/strelka/httprequest/negotiation.rb, line 232
def accepts_language?( language )
self.log.debug "Checking to see if request accepts language: %p" % [ language ]
found_language = self.accepted_languages.find {|langcode| langcode =~ language }
self.log.debug " find returned: %p" % [ found_language ]
return found_language && found_language.qvalue.nonzero?
end
Returns boolean true/false if the requestor can handle the given
language
, not including the wildcard language if present.
# File lib/strelka/httprequest/negotiation.rb, line 243
def explicitly_accepts_language?( language )
non_wildcard_languages = self.accepted_languages.reject {|enc| enc.content_coding.nil? }
found_language = non_wildcard_languages.find {|enc| enc =~ language }
return found_language.qvalue.nonzero?
end
Parse the receiver's 'Accept-Language' header and return it as an Array of Strelka::HTTPRequest::Language objects.
# File lib/strelka/httprequest/negotiation.rb, line 253
def parse_accept_language_header
return self.parse_negotiation_header( :accept_language, Strelka::HTTPRequest::Language ) do
Strelka::HTTPRequest::Language.new( '*' )
end
end
Return an Array of Strelka::HTTPRequest::MediaType objects for each type in the 'Accept' header.
# File lib/strelka/httprequest/negotiation.rb, line 67
def accepted_mediatypes
@accepted_mediatypes ||= self.parse_accept_header
return @accepted_mediatypes
end
Returns boolean true/false if the requestor can handle the given
content_type
.
# File lib/strelka/httprequest/negotiation.rb, line 76
def accepts?( content_type )
self.log.debug "Checking to see if request accepts %p" % [ content_type ]
atype = self.accepted_types.find {|type| type =~ content_type }
self.log.debug " find returned: %p" % [ atype ]
return atype ? true : false
end
Returns boolean true/false if the requestor can handle the given
content_type
, not including mime wildcards.
# File lib/strelka/httprequest/negotiation.rb, line 87
def explicitly_accepts?( content_type )
non_wildcard_types = self.accepted_types.reject {|param| param.subtype.nil? }
return non_wildcard_types.find {|type| type =~ content_type } ? true : false
end
Parse the receiver's 'Accept' header and return it as an Array of Strelka::HTTPRequest::MediaType objects.
# File lib/strelka/httprequest/negotiation.rb, line 96
def parse_accept_header
return self.parse_negotiation_header( :accept, Strelka::HTTPRequest::MediaType ) do
Strelka::HTTPRequest::MediaType.new( '*', '*' )
end
rescue => err
self.log.error "%p while parsing the Accept header: %s" % [ err.class, err.message ]
self.log.debug " %s" % [ err.backtrace.join("\n ") ]
finish_with HTTP::BAD_REQUEST, "Malformed Accept header"
end