diff options
author | Gibheer <gibheer@gmail.com> | 2012-11-16 13:59:12 +0100 |
---|---|---|
committer | Gibheer <gibheer@gmail.com> | 2012-11-16 18:13:07 +0100 |
commit | be5cd61bb92f9f802bf30e98064d310168e690c2 (patch) | |
tree | 625224f586b2dfbd5540d8b827eff6207ffe48a9 /lib | |
parent | a7d3106df2840b4173d762b8cc8c35d6bfbb7065 (diff) |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/zero/request.rb | 2 | ||||
-rw-r--r-- | lib/zero/request/accept.rb | 70 | ||||
-rw-r--r-- | lib/zero/request/accept_type.rb | 66 |
3 files changed, 80 insertions, 58 deletions
diff --git a/lib/zero/request.rb b/lib/zero/request.rb index 6b6ff01..9be17e9 100644 --- a/lib/zero/request.rb +++ b/lib/zero/request.rb @@ -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 diff --git a/lib/zero/request/accept.rb b/lib/zero/request/accept.rb index 9ab1dfc..0a97a81 100644 --- a/lib/zero/request/accept.rb +++ b/lib/zero/request/accept.rb @@ -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 - 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] + 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 - # 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 diff --git a/lib/zero/request/accept_type.rb b/lib/zero/request/accept_type.rb new file mode 100644 index 0000000..db5a000 --- /dev/null +++ b/lib/zero/request/accept_type.rb @@ -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 |