webmention-endpoint 1.0.1 → 2.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
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f128c7d8a768bf568687aada16dbe1e9a16cccd8
|
4
|
+
data.tar.gz: d0098d15f6ff9f5602ff4942101faf3770c536ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50b40491e45e6c71198ff81c4b57acbb89e8338c1aee7d474b91c8dddfed996e6d060ad32db5c860c4f7e46abd740ad82cec3ee476456158fbcf47154bdb69c3
|
7
|
+
data.tar.gz: 0c283b3de0f2f72d0092214b2e9da15c566581209c208fb9fe6ae55c81dde5772336383fc5ebf9d83b7256dca1dbfd0f0969bf4e8a4475ec1b7450c8aa17677b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.0.0 / 2018-08-18
|
4
|
+
|
5
|
+
- Renames `Webmention::Endpoint::Response` class to `Webmention::Endpoint::Request` ([db485f3](https://github.com/jgarber623/webmention-endpoint-ruby/commit/db485f3)).
|
6
|
+
- Removes `Webmention::Endpoint::Discover` class and moves its functionality to `Webmention::Endpoint::Client` ([a9ff0a9](https://github.com/jgarber623/webmention-endpoint-ruby/commit/a9ff0a9)).
|
7
|
+
|
3
8
|
## 1.0.1 / 2018-07-29
|
4
9
|
|
5
10
|
- Raise an `ArgumentError` when `Client` instantiated with non-absolute URI ([64f161e](https://github.com/jgarber623/webmention-endpoint-ruby/commit/64f161e)).
|
data/lib/webmention/endpoint.rb
CHANGED
@@ -6,8 +6,7 @@ require 'nokogiri'
|
|
6
6
|
require 'webmention/endpoint/version'
|
7
7
|
require 'webmention/endpoint/error'
|
8
8
|
require 'webmention/endpoint/client'
|
9
|
-
require 'webmention/endpoint/
|
10
|
-
require 'webmention/endpoint/response'
|
9
|
+
require 'webmention/endpoint/request'
|
11
10
|
|
12
11
|
module Webmention
|
13
12
|
module Endpoint
|
@@ -1,6 +1,18 @@
|
|
1
1
|
module Webmention
|
2
2
|
module Endpoint
|
3
3
|
class Client
|
4
|
+
# Ultra-orthodox pattern matching allowed values in Link header `rel` parameter
|
5
|
+
# https://tools.ietf.org/html/rfc8288#section-3.3
|
6
|
+
REGEXP_REG_REL_TYPE_PATTERN = '[a-z\d][a-z\d\-\.]*'.freeze
|
7
|
+
|
8
|
+
# Liberal pattern matching a string of text between angle brackets
|
9
|
+
# https://tools.ietf.org/html/rfc5988#section-5.1
|
10
|
+
REGEXP_TARGET_URI_PATTERN = /^<(.*)>;/
|
11
|
+
|
12
|
+
# Ultra-orthodox pattern matching Link header `rel` parameter including a `webmention` value
|
13
|
+
# https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint-p-1
|
14
|
+
REGEXP_WEBMENTION_REL_PATTERN = /(?:;|\s)rel="?(?:#{REGEXP_REG_REL_TYPE_PATTERN}+\s)?webmention(?:\s#{REGEXP_REG_REL_TYPE_PATTERN})?"?/
|
15
|
+
|
4
16
|
def initialize(url)
|
5
17
|
raise ArgumentError, "url must be a String (given #{url.class.name})" unless url.is_a?(String)
|
6
18
|
|
@@ -12,11 +24,50 @@ module Webmention
|
|
12
24
|
end
|
13
25
|
|
14
26
|
def endpoint
|
15
|
-
|
27
|
+
return unless endpoint_from_http_request
|
28
|
+
|
29
|
+
@endpoint ||= Absolutely.to_absolute_uri(base: response.uri.to_s, relative: endpoint_from_http_request)
|
30
|
+
rescue Absolutely::InvalidURIError => error
|
31
|
+
raise InvalidURIError, error
|
16
32
|
end
|
17
33
|
|
18
34
|
def response
|
19
|
-
@response ||=
|
35
|
+
@response ||= Request.new(@uri).response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def endpoint_from_body
|
41
|
+
return unless response.mime_type == 'text/html'
|
42
|
+
|
43
|
+
doc = Nokogiri::HTML(response.body.to_s)
|
44
|
+
|
45
|
+
# Search response body for first `a` or `link` element with valid `rel` and `href` attributes
|
46
|
+
link_element = doc.css('[rel~="webmention"][href]').select { |element| %w[a link].include?(element.name) }.shift
|
47
|
+
|
48
|
+
return link_element['href'] if link_element
|
49
|
+
end
|
50
|
+
|
51
|
+
def endpoint_from_headers
|
52
|
+
link_headers = response.headers.get('link')
|
53
|
+
|
54
|
+
return unless link_headers
|
55
|
+
|
56
|
+
# Split Link headers with multiple values, flatten the resulting array, and strip whitespace
|
57
|
+
# https://webmention.rocks/test/19
|
58
|
+
link_headers = link_headers.map { |header| header.split(',') }.flatten.map(&:strip)
|
59
|
+
|
60
|
+
webmention_header = link_headers.find { |header| header.match?(REGEXP_WEBMENTION_REL_PATTERN) }
|
61
|
+
|
62
|
+
return unless webmention_header
|
63
|
+
|
64
|
+
endpoint_match_data = webmention_header.match(REGEXP_TARGET_URI_PATTERN)
|
65
|
+
|
66
|
+
return endpoint_match_data[1] if endpoint_match_data
|
67
|
+
end
|
68
|
+
|
69
|
+
def endpoint_from_http_request
|
70
|
+
@endpoint_from_http_request ||= endpoint_from_headers || endpoint_from_body || nil
|
20
71
|
end
|
21
72
|
end
|
22
73
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webmention-endpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.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: 2018-
|
11
|
+
date: 2018-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -211,9 +211,8 @@ files:
|
|
211
211
|
- Rakefile
|
212
212
|
- lib/webmention/endpoint.rb
|
213
213
|
- lib/webmention/endpoint/client.rb
|
214
|
-
- lib/webmention/endpoint/discover.rb
|
215
214
|
- lib/webmention/endpoint/error.rb
|
216
|
-
- lib/webmention/endpoint/
|
215
|
+
- lib/webmention/endpoint/request.rb
|
217
216
|
- lib/webmention/endpoint/version.rb
|
218
217
|
- webmention-endpoint.gemspec
|
219
218
|
homepage: https://github.com/jgarber623/webmention-endpoint-ruby
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module Webmention
|
2
|
-
module Endpoint
|
3
|
-
class Discover
|
4
|
-
# Ultra-orthodox pattern matching allowed values in Link header `rel` parameter
|
5
|
-
# https://tools.ietf.org/html/rfc8288#section-3.3
|
6
|
-
REGEXP_REG_REL_TYPE_PATTERN = '[a-z\d][a-z\d\-\.]*'.freeze
|
7
|
-
|
8
|
-
# Liberal pattern matching a string of text between angle brackets
|
9
|
-
# https://tools.ietf.org/html/rfc5988#section-5.1
|
10
|
-
REGEXP_TARGET_URI_PATTERN = /^<(.*)>;/
|
11
|
-
|
12
|
-
# Ultra-orthodox pattern matching Link header `rel` parameter including a `webmention` value
|
13
|
-
# https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint-p-1
|
14
|
-
REGEXP_WEBMENTION_REL_PATTERN = /(?:;|\s)rel="?(?:#{REGEXP_REG_REL_TYPE_PATTERN}+\s)?webmention(?:\s#{REGEXP_REG_REL_TYPE_PATTERN})?"?/
|
15
|
-
|
16
|
-
def initialize(response)
|
17
|
-
raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
|
18
|
-
|
19
|
-
@response = response
|
20
|
-
end
|
21
|
-
|
22
|
-
def endpoint
|
23
|
-
return unless endpoint_from_http_request
|
24
|
-
|
25
|
-
@endpoint ||= Absolutely.to_absolute_uri(base: @response.uri.to_s, relative: endpoint_from_http_request)
|
26
|
-
rescue Absolutely::InvalidURIError => error
|
27
|
-
raise InvalidURIError, error
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def endpoint_from_body
|
33
|
-
return unless @response.mime_type == 'text/html'
|
34
|
-
|
35
|
-
doc = Nokogiri::HTML(@response.body.to_s)
|
36
|
-
|
37
|
-
# Search response body for first `a` or `link` element with valid `rel` and `href` attributes
|
38
|
-
link_element = doc.css('[rel~="webmention"][href]').select { |element| %w[a link].include?(element.name) }.shift
|
39
|
-
|
40
|
-
return link_element['href'] if link_element
|
41
|
-
end
|
42
|
-
|
43
|
-
def endpoint_from_headers
|
44
|
-
link_headers = @response.headers.get('link')
|
45
|
-
|
46
|
-
return unless link_headers
|
47
|
-
|
48
|
-
# Split Link headers with multiple values, flatten the resulting array, and strip whitespace
|
49
|
-
# https://webmention.rocks/test/19
|
50
|
-
link_headers = link_headers.map { |header| header.split(',') }.flatten.map(&:strip)
|
51
|
-
|
52
|
-
webmention_header = link_headers.find { |header| header.match?(REGEXP_WEBMENTION_REL_PATTERN) }
|
53
|
-
|
54
|
-
return unless webmention_header
|
55
|
-
|
56
|
-
endpoint_match_data = webmention_header.match(REGEXP_TARGET_URI_PATTERN)
|
57
|
-
|
58
|
-
return endpoint_match_data[1] if endpoint_match_data
|
59
|
-
end
|
60
|
-
|
61
|
-
def endpoint_from_http_request
|
62
|
-
@endpoint_from_http_request ||= endpoint_from_headers || endpoint_from_body || nil
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|