module Strelka::HTTPRequest::Negotiation

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' )

Public Class Methods

new( * ) click to toggle source

Extension callback – add instance variables to extended objects.

Calls superclass method
# File lib/strelka/httprequest/negotiation.rb, line 24
def initialize( * )
        super
        @accepted_mediatypes = nil
        @accepted_charsets   = nil
        @accepted_encodings  = nil
        @accepted_languages  = nil
end

Public Instance Methods

parse_negotiation_header( header, paramclass ) { || ... } click to toggle source

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

Charset negotiation

↑ top

Public Instance Methods

accept_charset?( charset )
Alias for: accepts_charset?
accepted_charsets() click to toggle source

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
accepts_charset?( charset ) click to toggle source

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
Also aliased as: accept_charset?
explicitly_accept_charset?( charset )
explicitly_accepts_charset?( charset ) click to toggle source

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
Also aliased as: explicitly_accept_charset?
parse_accept_charset_header() click to toggle source

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

Encoding negotiation

↑ top

Public Instance Methods

accept_encoding?( encoding )
Alias for: accepts_encoding?
accepted_encodings() click to toggle source

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
accepts_encoding?( encoding ) click to toggle source

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
Also aliased as: accept_encoding?
explicitly_accept_encoding?( encoding )
explicitly_accepts_encoding?( encoding ) click to toggle source

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
Also aliased as: explicitly_accept_encoding?
parse_accept_encoding_header() click to toggle source

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

Language negotiation

↑ top

Public Instance Methods

accept_language?( language )
Alias for: accepts_language?
accepted_languages() click to toggle source

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
accepts_language?( language ) click to toggle source

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
Also aliased as: accept_language?
explicitly_accept_language?( language )
explicitly_accepts_language?( language ) click to toggle source

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
Also aliased as: explicitly_accept_language?
parse_accept_language_header() click to toggle source

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

Mediatype negotiation

↑ top

Public Instance Methods

accept?( content_type )
Alias for: accepts?
accepted_mediatypes() click to toggle source

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
Also aliased as: accepted_types
accepted_types()
Alias for: accepted_mediatypes
accepts?( content_type ) click to toggle source

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
Also aliased as: accept?
explicitly_accept?( content_type )
Alias for: explicitly_accepts?
explicitly_accepts?( content_type ) click to toggle source

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
Also aliased as: explicitly_accept?
parse_accept_header() click to toggle source

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