http-accept 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2fcbdc6b5f7e1e3cc175971bfd4e2649774b4fe
4
- data.tar.gz: 671c3b4ff9b5a4d2b94ca08d9ab380a4f8a8f498
3
+ metadata.gz: 4850286afbb8944881e7bbf281c13b68cf2b3ec5
4
+ data.tar.gz: 8d35dbe069f01a8c15777dca2f3aaeee88188106
5
5
  SHA512:
6
- metadata.gz: 17f635535d0cb476d90d3fa8ed132c5599f14ed71acb8c3aa6db3c9c615e55beb1081813342109bc04172beddb3689248c22598a4c3584a08fd527302259b597
7
- data.tar.gz: cf4474a4a0f87ec94dc748724b86a2216250cacdf02cf1f056483efe16d4b7e7627638aa3881e65c27aa77a810b6bb77a7e2b57f81b027061f70e51e0e8f136f
6
+ metadata.gz: bd96bc2dd0c9bf3f757d8c655d3ee493d2099e3f0995ee873b0df189714ce71316b4ab80460ba05af62feb3fcb1d9a7f4354280a559cd0b3cd974103cac38afb
7
+ data.tar.gz: fcc95a0eb6068af7715c5d8c9bac5ca74d91a2a5bef2cb7e0aaa51ef47e9bfaa58c33e0019219e49452ea6702657315c2c95d0e5cb80a7d9f2f819cc5d609d1f
@@ -24,6 +24,7 @@ require_relative 'accept/version'
24
24
 
25
25
  # Accept: header
26
26
  require_relative 'accept/media_types'
27
+ require_relative 'accept/content_type'
27
28
 
28
29
  # Accept-Language: header
29
30
  require_relative 'accept/languages'
@@ -0,0 +1,36 @@
1
+ # Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'media_types'
22
+ require_relative 'quoted_string'
23
+
24
+ module HTTP
25
+ module Accept
26
+ # A content type is different from a media range, in that a content type should not have any wild cards.
27
+ class ContentType < MediaTypes::MediaRange
28
+ def initialize(mime_type, parameters = {})
29
+ # We do some basic validation here:
30
+ raise ArgumentError.new("#{self.class} can not have wildcards: #{mime_type}") if mime_type.include? '*'
31
+
32
+ super
33
+ end
34
+ end
35
+ end
36
+ end
@@ -33,35 +33,31 @@ module HTTP
33
33
 
34
34
  # Map a set of mime types to objects.
35
35
  class Map
36
- WILDCARD = '*'.freeze
36
+ WILDCARD = "*/*".freeze
37
37
 
38
38
  def initialize
39
- @media_types = Hash.new{|h,k| h[k] = {}}
40
-
41
- # Primarily for implementing #freeze efficiently.
42
- @all = []
39
+ @media_types = {}
43
40
  end
44
41
 
45
42
  def freeze
46
- @media_types.freeze
47
- @media_types.each{|key,value| value.freeze}
48
-
49
- @all.freeze
50
- @all.each(&:freeze)
51
-
52
- super
43
+ unless frozen?
44
+ @media_types.freeze
45
+ @media_types.each{|key,value| value.freeze}
46
+
47
+ super
48
+ end
53
49
  end
54
50
 
55
51
  # Given a list of content types (e.g. from browser_preferred_content_types), return the best converter.
56
52
  def for(media_types)
57
53
  media_types.each do |media_range|
58
- type, subtype = media_range.split
54
+ mime_type = case media_range
55
+ when String then media_range
56
+ else media_range.mime_type
57
+ end
59
58
 
60
- # TODO: Could be improved using dig?
61
- if major_type = @media_types.fetch(type, nil)
62
- if object = major_type.fetch(subtype, nil)
63
- return object, media_range
64
- end
59
+ if object = @media_types[mime_type]
60
+ return object, media_range
65
61
  end
66
62
  end
67
63
 
@@ -72,26 +68,43 @@ module HTTP
72
68
  def << object
73
69
  type, subtype = object.content_type.split('/')
74
70
 
75
- if @media_types.empty?
76
- @media_types[WILDCARD][WILDCARD] = object
77
- end
78
-
79
- if @media_types[type].empty?
80
- @media_types[type][WILDCARD] = object
81
- end
71
+ @media_types[WILDCARD] = object if @media_types.empty?
72
+ @media_types["#{type}/*"] ||= object
73
+ @media_types["#{type}/#{subtype}"] ||= object
82
74
 
83
- @media_types[type][subtype] = object
84
- @all << object
75
+ return self
85
76
  end
86
77
  end
87
78
 
88
79
  class MediaRange < Struct.new(:mime_type, :parameters)
80
+ def parameters_string
81
+ return '' if parameters == nil or parameters.empty?
82
+
83
+ parameters.collect do |key, value|
84
+ "; #{key.to_s}=#{QuotedString.quote(value.to_s)}"
85
+ end.join
86
+ end
87
+
88
+ def === other
89
+ if other.is_a? self.class
90
+ super
91
+ else
92
+ return self.mime_type === other
93
+ end
94
+ end
95
+
96
+ def to_s
97
+ @to_s || "#{mime_type}#{parameters_string}"
98
+ end
99
+
100
+ alias to_str to_s
101
+
89
102
  def quality_factor
90
103
  parameters.fetch('q', 1.0).to_f
91
104
  end
92
105
 
93
- def split
94
- @type, @subtype = mime_type.split('/')
106
+ def split(on = '/', count = 2)
107
+ mime_type.split(on, count)
95
108
  end
96
109
 
97
110
  def self.parse(scanner, normalize_whitespace = true)
@@ -39,6 +39,15 @@ module HTTP
39
39
 
40
40
  return value
41
41
  end
42
+
43
+ # Quote a string if required. Doesn't handle newlines correctly currently.
44
+ def self.quote(value, force = false)
45
+ if value =~ /"/ or force
46
+ "\"#{value.gsub(/["\\]/, "\\\\\\0")}\""
47
+ else
48
+ return value
49
+ end
50
+ end
42
51
  end
43
52
  end
44
53
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module HTTP
22
22
  module Accept
23
- VERSION = "1.1.3"
23
+ VERSION = "1.2.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-accept
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -68,6 +68,7 @@ files:
68
68
  - Rakefile
69
69
  - http-accept.gemspec
70
70
  - lib/http/accept.rb
71
+ - lib/http/accept/content_type.rb
71
72
  - lib/http/accept/languages.rb
72
73
  - lib/http/accept/media_types.rb
73
74
  - lib/http/accept/parse_error.rb