0
0
Fork 0

this adds a new accept type

This new class handles various accept strings and makes them available
throught the same API. This way, language and media type feels the same.
This commit is contained in:
Gibheer 2012-11-16 13:59:12 +01:00
parent a7d3106df2
commit be5cd61bb9
3 changed files with 80 additions and 58 deletions

View File

@ -55,7 +55,7 @@ module Zero
# get the media types
# @return [Accept] on Accept object managing all types and their order
def media_types
@accept ||= Request::Accept.new(@env[CONST_HTTP_ACCEPT])
@accept ||= Request::Accept.new(@env)
end
# get the method of the request

View File

@ -1,3 +1,5 @@
require_relative 'accept_type'
module Zero
class Request
# encapsulates the accept header to easier work with
@ -7,6 +9,10 @@ module Zero
MEDIA_PARAM_SEPERATOR = ';'
MEDIA_QUALITY_REGEX = /q=[01]\./
KEY_HTTP_ACCEPT = 'HTTP_ACCEPT'
KEY_HTTP_ACCEPT_LANGUAGE = 'HTTP_ACCEPT_LANGUAGE'
KEY_HTTP_ACCEPT_ENCODING = 'HTTP_ACCEPT_ENCODING'
def self.map=(map)
@@map = map
end
@ -16,65 +22,15 @@ module Zero
end
# create a new accept object
def initialize(accept_string)
if accept_string.nil?
@types = []
else
@types = parse_media_types(accept_string)
end
def initialize(environment)
@accept_types = AcceptType.new(environment[KEY_HTTP_ACCEPT])
@accept_language = AcceptType.new(environment[KEY_HTTP_ACCEPT_LANGUAGE])
@accept_encoding = AcceptType.new(environment[KEY_HTTP_ACCEPT_ENCODING])
end
# return the preferred type
# @return String the preferred media type
def preferred
@types.first
end
# iterate over all media types
def each
@types.each {|type| yield type}
end
private
# converts the accept string to a useable array
# @param accept_string the string containing media ranges and options
def parse_media_types(accept_string = '*/*')
accept_string.
gsub(/\s/, '').
split(MEDIA_TYPE_SEPERATOR).
map do |accept_range|
extract_order(*accept_range.split(MEDIA_PARAM_SEPERATOR))
end.
sort_by(&:last).
map(&:first)
end
# extract the order of the type
# @param media_type the type itself
# @param params further options to the type
# @return Array the media type and quality in that order
def extract_order(media_type, *params)
params.each do |param|
if param.match(MEDIA_QUALITY_REGEX)
return [map_type(media_type), 10 - param[4..-1].to_i]
end
end
[map_type(media_type), 0]
end
# map media types to the type given in the map
# @param type [String] the media type
# @return the media type of the mapping or the original
def map_type(type)
return map[type] if map.has_key?(type)
type
end
# a small wrapper to the class method
def map
self.class.map
end
attr_reader :accept_types
attr_reader :accept_language
attr_reader :accept_encoding
end
end
end

View File

@ -0,0 +1,66 @@
module Zero
class Request
# This class provides an interface to access information of accept schemas.
class AcceptType
MEDIA_TYPE_SEPERATOR = ','
MEDIA_PARAM_SEPERATOR = ';'
MEDIA_QUALITY_REGEX = /q=[01]\./
# create a new instance of AcceptType
def initialize(string)
if string.nil?
@elements = []
else
@elements = parse_elements(string)
end
end
# return the preferred type
# @return String the preferred media type
def preferred
@elements.first
end
# iterate over all media types
def each
@elements.each {|element| yield element}
end
private
# converts the accept string to a useable array
# @param string the string containing media ranges and options
def parse_elements(string = '*/*')
string.
gsub(/\s/, '').
split(MEDIA_TYPE_SEPERATOR).
map do |accept_range|
extract_order(*accept_range.split(MEDIA_PARAM_SEPERATOR))
end.
sort_by(&:last).
map(&:first)
end
# extract the order of the type
# @param media_type the type itself
# @param params further options to the type
# @return Array the media type and quality in that order
def extract_order(media_type, *params)
params.each do |param|
if param.match(MEDIA_QUALITY_REGEX)
return [media_type, 10 - param[4..-1].to_i]
end
end
[media_type, 0]
end
# map media types to the type given in the map
# @param type [String] the media type
# @return the media type of the mapping or the original
def map_type(type)
return map[type] if map.has_key?(type)
type
end
end
end
end