rack-linkeddata 2.2.3 → 3.0.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
- SHA1:
3
- metadata.gz: 76405985288216619079282ed9afa6016682539b
4
- data.tar.gz: a5d9f2ae9d53b0a51c74d03f8d899080e4affc51
2
+ SHA256:
3
+ metadata.gz: bc9deb8760334ad2f933b56890f20a8c7cf5f179ddce2c46d0b301c10f8391e5
4
+ data.tar.gz: 791f3460f9ea1ac579b120fb450c6c092b3afdfaf2f0c2b9dd9732ac9236cb00
5
5
  SHA512:
6
- metadata.gz: 00d70e3a7aec1c180ff8d648cee4047cbd0c9b9c1b6a929549378523da2c09e72c39773396b6f4b567409b9dd0b920d79bf41b67f442b21f0351cd393cbc2aae
7
- data.tar.gz: 8a02cba64f7fee7c00694b85e095c6ea0df73d88a970c0f191805db6fcc5afd30eb64155783f842ed4977f4158553a07d1e2044c9fbac5e165784ce14dcc6539
6
+ metadata.gz: e6f32f42b0449dc2aef3752f3ede3b1313ee08f17c122a30cab1f907b1c36bba7233a12f500320b63cce689588d6f348a3d867afc39a2d862a974701cb5806f3
7
+ data.tar.gz: ea371601178e5f934cf45604e86444286954c7690bc0e665e4ab0613aaff4ceb98061f07a0890115d217754cb2c95f6ce90baf2b20484396d8589c7f73153d1d
data/AUTHORS CHANGED
@@ -1 +1,2 @@
1
1
  * Arto Bendiken <arto.bendiken@gmail.com>
2
+ * Gregg Kellogg <gregg@greggkellogg.net>
data/README.md CHANGED
@@ -98,8 +98,8 @@ for N-Triples, N-Quads, Turtle, RDF/XML, RDF/JSON, JSON-LD, RDFa, TriG and TriX.
98
98
 
99
99
  ## Dependencies
100
100
 
101
- * [Rack](http://rubygems.org/gems/rack) (~> 1.6)
102
- * [Linked Data](http://rubygems.org/gems/linkeddata) (~> 2.0)
101
+ * [Rack](http://rubygems.org/gems/rack) (~> 2.0)
102
+ * [Linked Data](http://rubygems.org/gems/linkeddata) (~> 3.0)
103
103
 
104
104
  ## Installation
105
105
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.3
1
+ 3.0.0
@@ -17,6 +17,7 @@ module Rack; module LinkedData
17
17
  # use Rack::LinkedData::ContentNegotiation, :default => 'application/rdf+xml'
18
18
  #
19
19
  # @see http://www4.wiwiss.fu-berlin.de/bizer/pub/LinkedDataTutorial/
20
+ # @see https://www.rubydoc.info/github/rack/rack/master/file/SPEC
20
21
  class ContentNegotiation
21
22
  DEFAULT_CONTENT_TYPE = "application/n-triples" # N-Triples
22
23
  VARY = {'Vary' => 'Accept'}.freeze
@@ -45,7 +46,7 @@ module Rack; module LinkedData
45
46
  # Inserts ordered content types into the environment as `ORDERED_CONTENT_TYPES` if an Accept header is present
46
47
  #
47
48
  # @param [Hash{String => String}] env
48
- # @return [Array(Integer, Hash, #each)]
49
+ # @return [Array(Integer, Hash, #each)] Status, Headers and Body
49
50
  # @see http://rack.rubyforge.org/doc/SPEC.html
50
51
  def call(env)
51
52
  env['ORDERED_CONTENT_TYPES'] = parse_accept_header(env['HTTP_ACCEPT']) if env.has_key?('HTTP_ACCEPT')
@@ -67,24 +68,33 @@ module Rack; module LinkedData
67
68
  # @param [Integer] status
68
69
  # @param [Hash{String => Object}] headers
69
70
  # @param [RDF::Enumerable] body
70
- # @return [Array(Integer, Hash, #each)]
71
+ # @return [Array(Integer, Hash, #each)] Status, Headers and Body
71
72
  def serialize(env, status, headers, body)
72
- begin
73
- writer, content_type = find_writer(env, headers)
74
- if writer
75
- # FIXME: don't overwrite existing Vary headers
76
- headers = headers.merge(VARY).merge('Content-Type' => content_type)
77
- [status, headers, [writer.dump(body, nil, @options)]]
78
- else
79
- not_acceptable
73
+ result, content_type = nil, nil
74
+ find_writer(env, headers) do |writer, ct, accept_params = {}|
75
+ begin
76
+ # Passes content_type as writer option to allow parameters to be extracted.
77
+ result, content_type = writer.dump(body, nil, @options.merge(accept_params: accept_params)), ct.split(';').first
78
+ break
79
+ rescue RDF::WriterError
80
+ # Continue to next writer
81
+ ct
82
+ rescue
83
+ ct
80
84
  end
81
- rescue RDF::WriterError => e
85
+ end
86
+
87
+ if result
88
+ headers = headers.merge(VARY).merge('Content-Type' => content_type)
89
+ [status, headers, [result]]
90
+ else
82
91
  not_acceptable
83
92
  end
84
93
  end
85
94
 
95
+ protected
86
96
  ##
87
- # Returns an `RDF::Writer` class for the given `env`.
97
+ # Yields an `RDF::Writer` class for the given `env`.
88
98
  #
89
99
  # If options contain a `:format` key, it identifies the specific format to use;
90
100
  # otherwise, if the environment has an HTTP_ACCEPT header, use it to find a writer;
@@ -92,39 +102,56 @@ module Rack; module LinkedData
92
102
  #
93
103
  # @param [Hash{String => String}] env
94
104
  # @param [Hash{String => Object}] headers
95
- # @return [Array(Class, String)]
105
+ # @yield |writer, content_type|
106
+ # @yield_param [RDF::Writer] writer
107
+ # @yield_param [String] content_type from accept media-range without parameters
108
+ # @yield_param [Hash{Symbol => String}] accept_params from accept media-range
96
109
  # @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
97
110
  def find_writer(env, headers)
98
111
  if @options[:format]
99
112
  format = @options[:format]
100
- writer = RDF::Writer.for(format.to_sym) unless format.is_a?(RDF::Format)
101
- return [writer, writer.format.content_type.first] if writer
113
+ writer = RDF::Writer.for(format.to_sym)
114
+ yield(writer, writer.format.content_type.first) if writer
102
115
  elsif env.has_key?('HTTP_ACCEPT')
103
116
  content_types = parse_accept_header(env['HTTP_ACCEPT'])
104
117
  content_types.each do |content_type|
105
- writer, content_type = find_writer_for_content_type(content_type)
106
- return [writer, content_type] if writer
118
+ find_writer_for_content_type(content_type) do |writer, ct, accept_params|
119
+ # Yields content type with parameters
120
+ yield(writer, ct, accept_params)
121
+ end
107
122
  end
108
- return nil
109
123
  else
110
124
  # HTTP/1.1 §14.1: "If no Accept header field is present, then it is
111
125
  # assumed that the client accepts all media types"
112
- find_writer_for_content_type(options[:default])
126
+ find_writer_for_content_type(options[:default]) do |writer, ct|
127
+ # Yields content type with parameters
128
+ yield(writer, ct)
129
+ end
113
130
  end
114
131
  end
115
132
 
116
133
  ##
117
- # Returns an `RDF::Writer` class for the given `content_type`.
134
+ # Yields an `RDF::Writer` class for the given `content_type`.
135
+ #
136
+ # Calls `Writer#accept?(content_type)` for matched content type to allow writers to further discriminate on how if to accept content-type with specified parameters.
118
137
  #
119
138
  # @param [String, #to_s] content_type
120
- # @return [Array(Class, String)]
139
+ # @yield |writer, content_type|
140
+ # @yield_param [RDF::Writer] writer
141
+ # @yield_param [String] content_type (including media-type parameters)
121
142
  def find_writer_for_content_type(content_type)
122
- writer = RDF::Writer.for(content_type: content_type) if content_type
123
- writer ? [writer, content_type] : nil
143
+ ct, *params = content_type.split(';').map(&:strip)
144
+ accept_params = params.inject({}) do |memo, pv|
145
+ p, v = pv.split('=').map(&:strip)
146
+ memo.merge(p.downcase.to_sym => v.sub(/^["']?([^"']*)["']?$/, '\1'))
147
+ end
148
+ formats = RDF::Format.each(content_type: ct, has_writer: true).to_a.reverse
149
+ formats.each do |format|
150
+ yield format.writer, (ct || format.content_type.first), accept_params if
151
+ format.writer.accept?(accept_params)
152
+ end
124
153
  end
125
154
 
126
- protected
127
-
128
155
  ##
129
156
  # Parses an HTTP `Accept` header, returning an array of MIME content
130
157
  # types ordered by the precedence rules defined in HTTP/1.1 §14.1.
@@ -135,14 +162,16 @@ module Rack; module LinkedData
135
162
  def parse_accept_header(header)
136
163
  entries = header.to_s.split(',')
137
164
  entries = entries.map { |e| accept_entry(e) }.sort_by(&:last).map(&:first)
138
- entries.map { |e| find_content_type_for_media_range(e) }
165
+ entries.map { |e| find_content_type_for_media_range(e) }.flatten
139
166
  end
140
167
 
168
+ # Returns pair of content_type (including non-'q' parameters)
169
+ # and array of quality, number of '*' in content-type, and number of non-'q' parameters
141
170
  def accept_entry(entry)
142
- type, *options = entry.delete(' ').split(';')
171
+ type, *options = entry.split(';').map(&:strip)
143
172
  quality = 0 # we sort smallest first
144
173
  options.delete_if { |e| quality = 1 - e[2..-1].to_f if e.start_with? 'q=' }
145
- [type, [quality, type.count('*'), 1 - options.size]]
174
+ [options.unshift(type).join(';'), [quality, type.count('*'), 1 - options.size]]
146
175
  end
147
176
 
148
177
  ##
@@ -189,7 +218,7 @@ module Rack; module LinkedData
189
218
  # @return [Array(Integer, Hash, #each)]
190
219
  def http_error(code, message = nil, headers = {})
191
220
  message = http_status(code) + (message.nil? ? "\n" : " (#{message})\n")
192
- [code, {'Content-Type' => "#{DEFAULT_CONTENT_TYPE}; charset=utf-8"}.merge(headers), [message]]
221
+ [code, {'Content-Type' => "text/plain"}.merge(headers), [message]]
193
222
  end
194
223
 
195
224
  ##
metadata CHANGED
@@ -1,97 +1,106 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-linkeddata
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
8
+ - Gregg Kellogg
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2017-12-14 00:00:00.000000000 Z
12
+ date: 2018-12-17 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: linkeddata
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '2.2'
20
- - - "<"
18
+ - - "~>"
21
19
  - !ruby/object:Gem::Version
22
- version: '4.0'
20
+ version: '3.0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
24
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '2.2'
30
- - - "<"
25
+ - - "~>"
31
26
  - !ruby/object:Gem::Version
32
- version: '4.0'
27
+ version: '3.0'
33
28
  - !ruby/object:Gem::Dependency
34
- name: rack
29
+ name: rdf
35
30
  requirement: !ruby/object:Gem::Requirement
36
31
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '1.6'
40
- - - "<"
32
+ - - "~>"
41
33
  - !ruby/object:Gem::Version
42
34
  version: '3.0'
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.8
43
38
  type: :runtime
44
39
  prerelease: false
45
40
  version_requirements: !ruby/object:Gem::Requirement
46
41
  requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '3.0'
47
45
  - - ">="
48
46
  - !ruby/object:Gem::Version
49
- version: '1.6'
50
- - - "<"
47
+ version: 3.0.8
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
51
60
  - !ruby/object:Gem::Version
52
- version: '3.0'
61
+ version: '2.0'
53
62
  - !ruby/object:Gem::Dependency
54
63
  name: yard
55
64
  requirement: !ruby/object:Gem::Requirement
56
65
  requirements:
57
66
  - - "~>"
58
67
  - !ruby/object:Gem::Version
59
- version: '0.8'
68
+ version: 0.9.12
60
69
  type: :development
61
70
  prerelease: false
62
71
  version_requirements: !ruby/object:Gem::Requirement
63
72
  requirements:
64
73
  - - "~>"
65
74
  - !ruby/object:Gem::Version
66
- version: '0.8'
75
+ version: 0.9.12
67
76
  - !ruby/object:Gem::Dependency
68
77
  name: rspec
69
78
  requirement: !ruby/object:Gem::Requirement
70
79
  requirements:
71
80
  - - "~>"
72
81
  - !ruby/object:Gem::Version
73
- version: '3.5'
82
+ version: '3.7'
74
83
  type: :development
75
84
  prerelease: false
76
85
  version_requirements: !ruby/object:Gem::Requirement
77
86
  requirements:
78
87
  - - "~>"
79
88
  - !ruby/object:Gem::Version
80
- version: '3.5'
89
+ version: '3.7'
81
90
  - !ruby/object:Gem::Dependency
82
91
  name: rack-test
83
92
  requirement: !ruby/object:Gem::Requirement
84
93
  requirements:
85
94
  - - "~>"
86
95
  - !ruby/object:Gem::Version
87
- version: '0.6'
96
+ version: '1.1'
88
97
  type: :development
89
98
  prerelease: false
90
99
  version_requirements: !ruby/object:Gem::Requirement
91
100
  requirements:
92
101
  - - "~>"
93
102
  - !ruby/object:Gem::Version
94
- version: '0.6'
103
+ version: '1.1'
95
104
  description: Rack middleware for Linked Data content negotiation.
96
105
  email: public-rdf-ruby@w3.org
97
106
  executables: []
@@ -125,8 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
134
  - !ruby/object:Gem::Version
126
135
  version: '0'
127
136
  requirements: []
128
- rubyforge_project: datagraph
129
- rubygems_version: 2.6.14
137
+ rubygems_version: 3.0.1
130
138
  signing_key:
131
139
  specification_version: 4
132
140
  summary: Linked Data content negotiation for Rack applications.