rack-linkeddata 2.2.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.