summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGibheer <gibheer@gmail.com>2012-11-16 13:59:12 +0100
committerGibheer <gibheer@gmail.com>2012-11-16 18:13:07 +0100
commitbe5cd61bb92f9f802bf30e98064d310168e690c2 (patch)
tree625224f586b2dfbd5540d8b827eff6207ffe48a9 /lib
parenta7d3106df2840b4173d762b8cc8c35d6bfbb7065 (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.rb2
-rw-r--r--lib/zero/request/accept.rb70
-rw-r--r--lib/zero/request/accept_type.rb66
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