From be5cd61bb92f9f802bf30e98064d310168e690c2 Mon Sep 17 00:00:00 2001 From: Gibheer Date: Fri, 16 Nov 2012 13:59:12 +0100 Subject: 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. --- lib/zero/request.rb | 2 +- lib/zero/request/accept.rb | 70 ++++++++--------------------------------- lib/zero/request/accept_type.rb | 66 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 58 deletions(-) create mode 100644 lib/zero/request/accept_type.rb (limited to 'lib') 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 -- cgit v1.2.3-70-g09d2