indieweb-endpoints 0.5.0 → 0.6.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
2
  SHA256:
3
- metadata.gz: 9cb1b27367683210b63651d8195e6d12013f994be97d8c216b2e2165429c4adb
4
- data.tar.gz: 587e29ea23c02d6de575cefbc6a5f9a808c5e6b47bf662ee138ceaadba03c57f
3
+ metadata.gz: ab63e805300751b251c129c817104bbc47b4fb8d90d758b1310734a7f9591dcf
4
+ data.tar.gz: 45431916ee155fc23df530dae6ebf51298675a6f065ab1163391a482612b9a40
5
5
  SHA512:
6
- metadata.gz: 1ca06c752aa3ff624d1ab3dbcad733d69bd5ab701ccdac754e7f5bc4e4d7c70ee8b42b23dd911448fb85fab44264e2e7f3c9c136cb23f5b4aaad282a21555ec7
7
- data.tar.gz: adbb98ffc16e4664d8ea47a94bdfb32b5fbd552155716a1928bf3b62fbdd4bc545768d00ce046101db454b8a71752acdb14330c99e57c1597eca73b8b0e71b93
6
+ metadata.gz: 2fc61c949330b86b0b8eaf784de934be79ec1cd85b700fb6b1e44bb4e27f877fe2bea99be0c444ae4fd9fe5793cae7218d035f8e5a0ee3ffe5abacdee86f0393
7
+ data.tar.gz: a0e56ed6e7be2bc619a2fb68d62e8898ebf62a45710b96bf78c1c32079d7ffe57c16c5066071b427c91418def99af5667f3ecd6327b5ff6712da60f945ab4531
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 / 2019-06-15
4
+
5
+ - Updates Parser-related classes to resolve [#2](https://github.com/indieweb/indieweb-endpoints-ruby/issues/2).
6
+
3
7
  ## 0.5.0 / 2019-05-09
4
8
 
5
9
  - Add support for Microsub endpoint discovery ([5e81d9f](https://github.com/indieweb/indieweb-endpoints-ruby/commit/5e81d9f)).
@@ -28,15 +28,16 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rake', '~> 12.3'
29
29
  spec.add_development_dependency 'reek', '~> 5.4'
30
30
  spec.add_development_dependency 'rspec', '~> 3.8'
31
- spec.add_development_dependency 'rubocop', '~> 0.68.1'
32
- spec.add_development_dependency 'rubocop-performance', '~> 1.1'
33
- spec.add_development_dependency 'rubocop-rspec', '~> 1.32'
31
+ spec.add_development_dependency 'rubocop', '~> 0.71.0'
32
+ spec.add_development_dependency 'rubocop-performance', '~> 1.3'
33
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.33'
34
34
  spec.add_development_dependency 'simplecov', '~> 0.16.1'
35
- spec.add_development_dependency 'simplecov-console', '~> 0.4.2'
36
- spec.add_development_dependency 'webmock', '~> 3.5'
35
+ spec.add_development_dependency 'simplecov-console', '~> 0.5.0'
36
+ spec.add_development_dependency 'webmock', '~> 3.6'
37
37
 
38
- spec.add_runtime_dependency 'absolutely', '~> 2.1'
38
+ spec.add_runtime_dependency 'absolutely', '~> 3.0'
39
39
  spec.add_runtime_dependency 'addressable', '~> 2.6'
40
40
  spec.add_runtime_dependency 'http', '~> 5.0.0.pre'
41
+ spec.add_runtime_dependency 'link-header-parser', '~> 0.1.0'
41
42
  spec.add_runtime_dependency 'nokogiri', '~> 1.10'
42
43
  end
@@ -29,22 +29,18 @@ module IndieWeb
29
29
  def results_from_http_request
30
30
  @results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
31
31
  end
32
- end
33
32
 
34
- class RedirectUriLinkElementParser < LinkElementParser
35
- def results
36
- link_elements.map { |element| element['href'] } if response_is_html && link_elements.any?
33
+ class RedirectUriLinkElementParser < BaseLinkElementParser
34
+ def results
35
+ link_elements.map { |element| element['href'] } if response_is_html && link_elements.any?
36
+ end
37
37
  end
38
- end
39
-
40
- class RedirectUriLinkHeaderParser < LinkHeaderParser
41
- def results
42
- return unless link_headers.any?
43
38
 
44
- link_headers.map do |header|
45
- endpoint_match_data = header.match(REGEXP_TARGET_URI_PATTERN)
39
+ class RedirectUriLinkHeaderParser < BaseLinkHeaderParser
40
+ def results
41
+ return unless link_headers
46
42
 
47
- endpoint_match_data[1] if endpoint_match_data
43
+ link_headers.map(&:target_uri)
48
44
  end
49
45
  end
50
46
  end
@@ -13,19 +13,19 @@ module IndieWeb
13
13
  def results_from_body
14
14
  WebmentionLinkElementParser.new(response, self.class.identifier).results
15
15
  end
16
- end
17
16
 
18
- class WebmentionLinkElementParser < LinkElementParser
19
- private
17
+ class WebmentionLinkElementParser < BaseLinkElementParser
18
+ private
20
19
 
21
- def link_element
22
- # Return first `a` or `link` element with valid `rel` attribute
23
- # https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
24
- @link_element ||= link_elements.find { |element| %w[a link].include?(element.name) }
25
- end
20
+ def link_element
21
+ # Return first `a` or `link` element with valid `rel` attribute
22
+ # https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
23
+ @link_element ||= link_elements.find { |element| %w[a link].include?(element.name) }
24
+ end
26
25
 
27
- def link_elements_css_selector
28
- @link_elements_css_selector ||= %([rel~="#{identifier}"][href]:not([href*="#"]))
26
+ def link_elements_css_selector
27
+ @link_elements_css_selector ||= %([rel~="#{identifier}"][href]:not([href*="#"]))
28
+ end
29
29
  end
30
30
  end
31
31
  end
@@ -23,101 +23,83 @@ module IndieWeb
23
23
  private
24
24
 
25
25
  def results_from_body
26
- LinkElementParser.new(response, self.class.identifier).results
26
+ BaseLinkElementParser.new(response, self.class.identifier).results
27
27
  end
28
28
 
29
29
  def results_from_headers
30
- LinkHeaderParser.new(response, self.class.identifier).results
30
+ BaseLinkHeaderParser.new(response, self.class.identifier).results
31
31
  end
32
32
 
33
33
  def results_from_http_request
34
34
  @results_from_http_request ||= results_from_headers || results_from_body || nil
35
35
  end
36
- end
37
36
 
38
- class LinkElementParser
39
- attr_reader :identifier, :response
37
+ class BaseLinkElementParser
38
+ attr_reader :identifier, :response
40
39
 
41
- def initialize(response, identifier)
42
- @response = response
43
- @identifier = identifier
44
- end
40
+ def initialize(response, identifier)
41
+ @response = response
42
+ @identifier = identifier
43
+ end
45
44
 
46
- def results
47
- link_element['href'] if response_is_html && link_element
48
- end
45
+ def results
46
+ link_element['href'] if response_is_html && link_element
47
+ end
49
48
 
50
- private
49
+ private
51
50
 
52
- def doc
53
- @doc ||= Nokogiri::HTML(response.body.to_s)
54
- end
51
+ def doc
52
+ @doc ||= Nokogiri::HTML(response.body.to_s)
53
+ end
55
54
 
56
- def link_element
57
- # Return first `link` element with valid `rel` attribute
58
- # https://www.w3.org/TR/indieauth/#discovery-1
59
- # https://www.w3.org/TR/micropub/#endpoint-discovery
60
- @link_element ||= link_elements.shift
61
- end
55
+ def link_element
56
+ # Return first `link` element with valid `rel` attribute
57
+ # https://www.w3.org/TR/indieauth/#discovery-1
58
+ # https://www.w3.org/TR/micropub/#endpoint-discovery
59
+ @link_element ||= link_elements.shift
60
+ end
62
61
 
63
- def link_elements
64
- @link_elements ||= doc.css(link_elements_css_selector)
65
- end
62
+ def link_elements
63
+ @link_elements ||= doc.css(link_elements_css_selector)
64
+ end
66
65
 
67
- def link_elements_css_selector
68
- @link_elements_css_selector ||= %(link[rel~="#{identifier}"][href]:not([href*="#"]))
69
- end
66
+ def link_elements_css_selector
67
+ @link_elements_css_selector ||= %(link[rel~="#{identifier}"][href]:not([href*="#"]))
68
+ end
70
69
 
71
- def response_is_html
72
- @response_is_html ||= response.mime_type == 'text/html'
70
+ def response_is_html
71
+ @response_is_html ||= response.mime_type == 'text/html'
72
+ end
73
73
  end
74
- end
75
74
 
76
- class LinkHeaderParser
77
- # Ultra-orthodox pattern matching allowed values in Link header `rel` parameter
78
- # https://tools.ietf.org/html/rfc8288#section-3.3
79
- REGEXP_REG_REL_TYPE_PATTERN = '[a-z\d][a-z\d\-\.]*'.freeze
75
+ class BaseLinkHeaderParser
76
+ attr_reader :identifier, :response
80
77
 
81
- # Liberal pattern capturing a string of text (excepting the octothorp) between angle brackets
82
- # https://tools.ietf.org/html/rfc5988#section-5.1
83
- REGEXP_TARGET_URI_PATTERN = '^<(.[^#]*)>;'.freeze
78
+ def initialize(response, identifier)
79
+ @response = response
80
+ @identifier = identifier
81
+ end
84
82
 
85
- attr_reader :identifier, :response
83
+ def results
84
+ return unless link_headers
86
85
 
87
- def initialize(response, identifier)
88
- @response = response
89
- @identifier = identifier
90
- end
91
-
92
- def results
93
- return unless link_header
86
+ link_headers.shift.target_uri
87
+ end
94
88
 
95
- endpoint_match_data = link_header.match(/#{REGEXP_TARGET_URI_PATTERN}/)
89
+ private
96
90
 
97
- return endpoint_match_data[1] if endpoint_match_data
98
- end
99
-
100
- private
91
+ def link_headers
92
+ @link_headers ||= begin
93
+ return unless parsed_link_headers
101
94
 
102
- def discrete_link_headers
103
- # Split Link headers with multiple values, flatten the resulting array, and strip whitespace
104
- # https://webmention.rocks/test/19
105
- @discrete_link_headers ||= response.headers.get('link').map { |header| header.split(',') }.flatten.map(&:strip)
106
- end
107
-
108
- def link_header
109
- @link_header ||= link_headers.shift
110
- end
111
-
112
- def link_headers
113
- # Reduce Link headers to those with valid `rel` attribute
114
- @link_headers ||= discrete_link_headers.find_all { |header| header.match?(/#{REGEXP_TARGET_URI_PATTERN}\s*#{regexp_rel_paramater_pattern}/) }
115
- end
95
+ # Reject endpoints that contain a fragment identifier
96
+ parsed_link_headers.reject { |parsed_link_header| Addressable::URI.parse(parsed_link_header.target_uri).fragment }
97
+ end
98
+ end
116
99
 
117
- def regexp_rel_paramater_pattern
118
- # Ultra-orthodox pattern matching Link header `rel` parameter including a matching identifier value
119
- # https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
120
- @regexp_rel_paramater_pattern ||= %(rel="?(?:#{REGEXP_REG_REL_TYPE_PATTERN}+\s)?#{identifier}(?:\s#{REGEXP_REG_REL_TYPE_PATTERN})?"?)
100
+ def parsed_link_headers
101
+ @parsed_link_headers ||= LinkHeaderParser.parse(response.headers.get('link'), base: response.uri.to_s).by_relation_type[identifier]
102
+ end
121
103
  end
122
104
  end
123
105
  end
@@ -1,5 +1,5 @@
1
1
  module IndieWeb
2
2
  module Endpoints
3
- VERSION = '0.5.0'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end
5
5
  end
@@ -1,6 +1,9 @@
1
+ require 'ostruct'
2
+
1
3
  require 'absolutely'
2
4
  require 'addressable/uri'
3
5
  require 'http'
6
+ require 'link-header-parser'
4
7
  require 'nokogiri'
5
8
 
6
9
  require 'indieweb/endpoints/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indieweb-endpoints
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Garber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-10 00:00:00.000000000 Z
11
+ date: 2019-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -58,42 +58,42 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.68.1
61
+ version: 0.71.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.68.1
68
+ version: 0.71.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-performance
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.1'
75
+ version: '1.3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.1'
82
+ version: '1.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.32'
89
+ version: '1.33'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '1.32'
96
+ version: '1.33'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,42 +114,42 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.4.2
117
+ version: 0.5.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.4.2
124
+ version: 0.5.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: webmock
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '3.5'
131
+ version: '3.6'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '3.5'
138
+ version: '3.6'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: absolutely
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '2.1'
145
+ version: '3.0'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '2.1'
152
+ version: '3.0'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: addressable
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 5.0.0.pre
181
+ - !ruby/object:Gem::Dependency
182
+ name: link-header-parser
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.1.0
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.1.0
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: nokogiri
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -235,7 +249,7 @@ licenses:
235
249
  - MIT
236
250
  metadata:
237
251
  bug_tracker_uri: https://github.com/indieweb/indieweb-endpoints-ruby/issues
238
- changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v0.5.0/CHANGELOG.md
252
+ changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v0.6.0/CHANGELOG.md
239
253
  post_install_message:
240
254
  rdoc_options: []
241
255
  require_paths: