Strelka::HTTPRequest::

Negotiation

module
Included Modules
Strelka::Constants

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

anchor
new( * )

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

Public Instance Methods

anchor
parse_negotiation_header( header, paramclass ) { || ... }

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

anchor
accept_charset?( charset )
Alias for: accepts_charset?
anchor
accepted_charsets()

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
anchor
accepts_charset?( charset )

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?
anchor
explicitly_accept_charset?( charset )
anchor
explicitly_accepts_charset?( charset )

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?
anchor
parse_accept_charset_header()

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

anchor
accept_encoding?( encoding )
Alias for: accepts_encoding?
anchor
accepted_encodings()

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
anchor
accepts_encoding?( encoding )

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?
anchor
explicitly_accept_encoding?( encoding )
anchor
explicitly_accepts_encoding?( encoding )

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?
anchor
parse_accept_encoding_header()

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

anchor
accept_language?( language )
Alias for: accepts_language?
anchor
accepted_languages()

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
anchor
accepts_language?( language )

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?
anchor
explicitly_accept_language?( language )
anchor
explicitly_accepts_language?( language )

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?
anchor
parse_accept_language_header()

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

anchor
accept?( content_type )
Alias for: accepts?
anchor
accepted_mediatypes()

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
anchor
accepted_types()
Alias for: accepted_mediatypes
anchor
accepts?( content_type )

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?
anchor
explicitly_accept?( content_type )
Alias for: explicitly_accepts?
anchor
explicitly_accepts?( content_type )

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?
anchor
parse_accept_header()

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