indieweb-endpoints 0.3.0 → 0.5.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 +4 -4
- data/.rubocop.yml +4 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +16 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +6 -5
- data/indieweb-endpoints.gemspec +8 -3
- data/lib/indieweb/endpoints.rb +10 -2
- data/lib/indieweb/endpoints/client.rb +5 -14
- data/lib/indieweb/endpoints/exceptions.rb +6 -6
- data/lib/indieweb/endpoints/http_request.rb +29 -0
- data/lib/indieweb/endpoints/parsers.rb +65 -33
- data/lib/indieweb/endpoints/parsers/microsub_parser.rb +13 -0
- data/lib/indieweb/endpoints/parsers/redirect_uri_parser.rb +18 -6
- data/lib/indieweb/endpoints/parsers/webmention_parser.rb +9 -1
- data/lib/indieweb/endpoints/version.rb +1 -1
- metadata +13 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cb1b27367683210b63651d8195e6d12013f994be97d8c216b2e2165429c4adb
|
4
|
+
data.tar.gz: 587e29ea23c02d6de575cefbc6a5f9a808c5e6b47bf662ee138ceaadba03c57f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ca06c752aa3ff624d1ab3dbcad733d69bd5ab701ccdac754e7f5bc4e4d7c70ee8b42b23dd911448fb85fab44264e2e7f3c9c136cb23f5b4aaad282a21555ec7
|
7
|
+
data.tar.gz: adbb98ffc16e4664d8ea47a94bdfb32b5fbd552155716a1928bf3b62fbdd4bc545768d00ce046101db454b8a71752acdb14330c99e57c1597eca73b8b0e71b93
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.5.0 / 2019-05-09
|
4
|
+
|
5
|
+
- Add support for Microsub endpoint discovery ([5e81d9f](https://github.com/indieweb/indieweb-endpoints-ruby/commit/5e81d9f)).
|
6
|
+
- Refactor parsers to ignore URLs with fragments ([797b376](https://github.com/indieweb/indieweb-endpoints-ruby/commit/797b376)).
|
7
|
+
- Rescue `NoMethodError` (for `nil`) and `TypeError` (for non-`String`) ([e33522e](https://github.com/indieweb/indieweb-endpoints-ruby/commit/e33522e)).
|
8
|
+
- Raise `ArgumentError` if url scheme is not `http` or `https` ([8eb1b1a](https://github.com/indieweb/indieweb-endpoints-ruby/commit/8eb1b1a)).
|
9
|
+
- Shorten up User Agent string ([f9717b4](https://github.com/indieweb/indieweb-endpoints-ruby/commit/f9717b4)).
|
10
|
+
- Refactor `HTTPRequest` class using specification defaults ([feef2ba](https://github.com/indieweb/indieweb-endpoints-ruby/commit/feef2ba)).
|
11
|
+
|
12
|
+
## 0.4.0 / 2019-05-01
|
13
|
+
|
14
|
+
- Add `IndieWeb::Endpoints.client` method ([c4d42d0](https://github.com/indieweb/indieweb-endpoints-ruby/commit/c4d42d0)).
|
15
|
+
- Rename base `Error` class to `IndieWebEndpointsError` ([d6d6f98](https://github.com/indieweb/indieweb-endpoints-ruby/commit/d6d6f98)).
|
16
|
+
- Add `HttpRequest` class ([7864cbd](https://github.com/indieweb/indieweb-endpoints-ruby/commit/7864cbd)).
|
17
|
+
|
3
18
|
## 0.3.0 / 2019-04-30
|
4
19
|
|
5
|
-
- `IndieWeb::Endpoints::Client#endpoints` returns an `OpenStruct` instead of a `Hash` ([c209b0b](https://github.com/indieweb/indieweb-endpoints-ruby/commit/c209b0b))
|
20
|
+
- `IndieWeb::Endpoints::Client#endpoints` returns an `OpenStruct` instead of a `Hash` ([c209b0b](https://github.com/indieweb/indieweb-endpoints-ruby/commit/c209b0b)).
|
6
21
|
|
7
22
|
## 0.2.0 / 2019-04-25
|
8
23
|
|
data/CONTRIBUTING.md
CHANGED
@@ -8,7 +8,7 @@ There are a couple ways you can help improve indieweb-endpoints-ruby:
|
|
8
8
|
|
9
9
|
## Getting Started
|
10
10
|
|
11
|
-
indieweb-endpoints-ruby is developed using Ruby 2.4.6 and is additionally tested against Ruby 2.5.5 and 2.6.
|
11
|
+
indieweb-endpoints-ruby is developed using Ruby 2.4.6 and is additionally tested against Ruby 2.5.5 and 2.6.3 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
|
12
12
|
|
13
13
|
Before making changes to indieweb-endpoints-ruby, you'll want to install Ruby 2.4.6. It's recommended that you use a Ruby version managment tool like [rbenv](https://github.com/rbenv/rbenv), [chruby](https://github.com/postmodern/chruby), or [rvm](https://github.com/rvm/rvm). Once you've installed Ruby 2.4.6 using your method of choice, install the project's gems by running:
|
14
14
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# indieweb-endpoints-ruby
|
2
2
|
|
3
|
-
**A Ruby gem for discovering a URL's [IndieAuth](https://indieweb.org/IndieAuth), [Micropub](https://indieweb.org/Micropub), and [Webmention](https://indieweb.org/Webmention) endpoints.**
|
3
|
+
**A Ruby gem for discovering a URL's [IndieAuth](https://indieweb.org/IndieAuth), [Micropub](https://indieweb.org/Micropub), [Microsub](https://indieweb.org/Microsub), and [Webmention](https://indieweb.org/Webmention) endpoints.**
|
4
4
|
|
5
5
|
[](https://rubygems.org/gems/indieweb-endpoints)
|
6
6
|
[](https://rubygems.org/gems/indieweb-endpoints)
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
Before installing and using indieweb-endpoints-ruby, you'll want to have [Ruby](https://www.ruby-lang.org) 2.4 (or newer) installed. It's recommended that you use a Ruby version managment tool like [rbenv](https://github.com/rbenv/rbenv), [chruby](https://github.com/postmodern/chruby), or [rvm](https://github.com/rvm/rvm).
|
20
20
|
|
21
|
-
indieweb-endpoints-ruby is developed using Ruby 2.4.6 and is additionally tested against Ruby 2.5.5 and 2.6.
|
21
|
+
indieweb-endpoints-ruby is developed using Ruby 2.4.6 and is additionally tested against Ruby 2.5.5 and 2.6.3 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
|
22
22
|
|
23
23
|
## Installation
|
24
24
|
|
@@ -56,6 +56,7 @@ This example will search `https://aaronparecki.com` for valid IndieAuth, Micropu
|
|
56
56
|
{
|
57
57
|
authorization_endpoint: 'https://aaronparecki.com/auth',
|
58
58
|
micropub: 'https://aaronparecki.com/micropub',
|
59
|
+
microsub: 'https://aperture.p3k.io/microsub/1',
|
59
60
|
redirect_uri: nil,
|
60
61
|
token_endpoint: 'https://aaronparecki.com/auth/token',
|
61
62
|
webmention: 'https://webmention.io/aaronpk/webmention'
|
@@ -66,12 +67,12 @@ Each attribute will return either a `String` representing a URL or `nil`. The `r
|
|
66
67
|
|
67
68
|
### Advanced Usage
|
68
69
|
|
69
|
-
Should the need arise, you may work
|
70
|
+
Should the need arise, you may work with the `IndieWeb::Endpoints::Client` class:
|
70
71
|
|
71
72
|
```ruby
|
72
73
|
require 'indieweb/endpoints'
|
73
74
|
|
74
|
-
client = IndieWeb::Endpoints
|
75
|
+
client = IndieWeb::Endpoints.client('https://aaronparecki.com')
|
75
76
|
|
76
77
|
puts client.response # => #<HTTP::Response …>
|
77
78
|
puts client.endpoints # => #<OpenStruct …>
|
@@ -80,7 +81,7 @@ puts client.endpoints.webmention # => 'https://webmention.io/aaronpk/webmention'
|
|
80
81
|
|
81
82
|
### Exception Handling
|
82
83
|
|
83
|
-
There are several exceptions that may be raised by indieweb-endpoints-ruby's underlying dependencies. These errors are raised as subclasses of `
|
84
|
+
There are several exceptions that may be raised by indieweb-endpoints-ruby's underlying dependencies. These errors are raised as subclasses of `IndieWebEndpointsError` (which itself is a subclass of `StandardError`).
|
84
85
|
|
85
86
|
From [jgarber623/absolutely](https://github.com/jgarber623/absolutely) and [sporkmonger/addressable](https://github.com/sporkmonger/addressable):
|
86
87
|
|
data/indieweb-endpoints.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.authors = ['Jason Garber']
|
12
12
|
spec.email = ['jason@sixtwothree.org']
|
13
13
|
|
14
|
-
spec.summary = 'Discover a URL’s IndieAuth, Micropub, and Webmention endpoints.'
|
14
|
+
spec.summary = 'Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.'
|
15
15
|
spec.description = spec.summary
|
16
16
|
spec.homepage = 'https://github.com/indieweb/indieweb-endpoints-ruby'
|
17
17
|
spec.license = 'MIT'
|
@@ -20,17 +20,22 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
+
spec.metadata = {
|
24
|
+
'bug_tracker_uri' => "#{spec.homepage}/issues",
|
25
|
+
'changelog_uri' => "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
|
26
|
+
}
|
27
|
+
|
23
28
|
spec.add_development_dependency 'rake', '~> 12.3'
|
24
29
|
spec.add_development_dependency 'reek', '~> 5.4'
|
25
30
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
26
|
-
spec.add_development_dependency 'rubocop', '~> 0.
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.68.1'
|
27
32
|
spec.add_development_dependency 'rubocop-performance', '~> 1.1'
|
28
33
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.32'
|
29
34
|
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
30
35
|
spec.add_development_dependency 'simplecov-console', '~> 0.4.2'
|
31
36
|
spec.add_development_dependency 'webmock', '~> 3.5'
|
32
37
|
|
33
|
-
spec.add_runtime_dependency 'absolutely', '~> 2.
|
38
|
+
spec.add_runtime_dependency 'absolutely', '~> 2.1'
|
34
39
|
spec.add_runtime_dependency 'addressable', '~> 2.6'
|
35
40
|
spec.add_runtime_dependency 'http', '~> 5.0.0.pre'
|
36
41
|
spec.add_runtime_dependency 'nokogiri', '~> 1.10'
|
data/lib/indieweb/endpoints.rb
CHANGED
@@ -7,19 +7,27 @@ require 'indieweb/endpoints/version'
|
|
7
7
|
require 'indieweb/endpoints/exceptions'
|
8
8
|
|
9
9
|
require 'indieweb/endpoints/client'
|
10
|
+
require 'indieweb/endpoints/http_request'
|
10
11
|
require 'indieweb/endpoints/registerable'
|
11
12
|
|
12
13
|
require 'indieweb/endpoints/parsers'
|
13
14
|
require 'indieweb/endpoints/parsers/authorization_endpoint_parser'
|
14
15
|
require 'indieweb/endpoints/parsers/micropub_parser'
|
16
|
+
require 'indieweb/endpoints/parsers/microsub_parser'
|
15
17
|
require 'indieweb/endpoints/parsers/redirect_uri_parser'
|
16
18
|
require 'indieweb/endpoints/parsers/token_endpoint_parser'
|
17
19
|
require 'indieweb/endpoints/parsers/webmention_parser'
|
18
20
|
|
19
21
|
module IndieWeb
|
20
22
|
module Endpoints
|
21
|
-
|
22
|
-
|
23
|
+
class << self
|
24
|
+
def client(url)
|
25
|
+
Client.new(url)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(url)
|
29
|
+
client(url).endpoints
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
@@ -1,19 +1,14 @@
|
|
1
1
|
module IndieWeb
|
2
2
|
module Endpoints
|
3
3
|
class Client
|
4
|
-
HTTP_HEADERS_OPTS = {
|
5
|
-
accept: '*/*',
|
6
|
-
user_agent: 'IndieAuth, Micropub, and Webmention Endpoint Discovery (https://rubygems.org/gems/indieweb-endpoints)'
|
7
|
-
}.freeze
|
8
|
-
|
9
4
|
def initialize(url)
|
10
|
-
|
11
|
-
|
12
|
-
@url = Addressable::URI.parse(url)
|
5
|
+
@uri = Addressable::URI.parse(url)
|
13
6
|
|
14
|
-
raise ArgumentError, 'url must be an absolute URL (e.g. https://example.com)' unless @
|
7
|
+
raise ArgumentError, 'url must be an absolute URL (e.g. https://example.com)' unless @uri.absolute? && @uri.scheme.match?(/^https?$/)
|
15
8
|
rescue Addressable::URI::InvalidURIError => exception
|
16
9
|
raise InvalidURIError, exception
|
10
|
+
rescue NoMethodError, TypeError
|
11
|
+
raise ArgumentError, "url must be a String (given #{url.class})"
|
17
12
|
end
|
18
13
|
|
19
14
|
def endpoints
|
@@ -21,11 +16,7 @@ module IndieWeb
|
|
21
16
|
end
|
22
17
|
|
23
18
|
def response
|
24
|
-
@response ||=
|
25
|
-
rescue HTTP::ConnectionError,
|
26
|
-
HTTP::TimeoutError,
|
27
|
-
HTTP::Redirector::TooManyRedirectsError => exception
|
28
|
-
raise IndieWeb::Endpoints.const_get(exception.class.name.split('::').last), exception
|
19
|
+
@response ||= HttpRequest.get(@uri)
|
29
20
|
end
|
30
21
|
end
|
31
22
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module IndieWeb
|
2
2
|
module Endpoints
|
3
|
-
class
|
3
|
+
class IndieWebEndpointsError < StandardError; end
|
4
4
|
|
5
|
-
class ArgumentError <
|
5
|
+
class ArgumentError < IndieWebEndpointsError; end
|
6
6
|
|
7
|
-
class ConnectionError <
|
7
|
+
class ConnectionError < IndieWebEndpointsError; end
|
8
8
|
|
9
|
-
class InvalidURIError <
|
9
|
+
class InvalidURIError < IndieWebEndpointsError; end
|
10
10
|
|
11
|
-
class TimeoutError <
|
11
|
+
class TimeoutError < IndieWebEndpointsError; end
|
12
12
|
|
13
|
-
class TooManyRedirectsError <
|
13
|
+
class TooManyRedirectsError < IndieWebEndpointsError; end
|
14
14
|
end
|
15
15
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module IndieWeb
|
2
|
+
module Endpoints
|
3
|
+
class HttpRequest
|
4
|
+
# Defaults derived from Webmention specification examples
|
5
|
+
# https://www.w3.org/TR/webmention/#limits-on-get-requests
|
6
|
+
HTTP_CLIENT_OPTS = {
|
7
|
+
follow: {
|
8
|
+
max_hops: 20
|
9
|
+
},
|
10
|
+
headers: {
|
11
|
+
accept: '*/*',
|
12
|
+
user_agent: 'IndieWeb Endpoint Discovery (https://rubygems.org/gems/indieweb-endpoints)'
|
13
|
+
},
|
14
|
+
timeout_options: {
|
15
|
+
connect_timeout: 5,
|
16
|
+
read_timeout: 5
|
17
|
+
}
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
def self.get(uri)
|
21
|
+
HTTP::Client.new(HTTP_CLIENT_OPTS).request(:get, uri)
|
22
|
+
rescue HTTP::ConnectionError,
|
23
|
+
HTTP::TimeoutError,
|
24
|
+
HTTP::Redirector::TooManyRedirectsError => exception
|
25
|
+
raise IndieWeb::Endpoints.const_get(exception.class.name.split('::').last), exception
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,13 +4,7 @@ module IndieWeb
|
|
4
4
|
extend Registerable
|
5
5
|
|
6
6
|
class BaseParser
|
7
|
-
|
8
|
-
# https://tools.ietf.org/html/rfc8288#section-3.3
|
9
|
-
REGEXP_REG_REL_TYPE_PATTERN = '[a-z\d][a-z\d\-\.]*'.freeze
|
10
|
-
|
11
|
-
# Liberal pattern matching a string of text between angle brackets
|
12
|
-
# https://tools.ietf.org/html/rfc5988#section-5.1
|
13
|
-
REGEXP_TARGET_URI_PATTERN = /^<(.*)>;/.freeze
|
7
|
+
attr_reader :response
|
14
8
|
|
15
9
|
def initialize(response)
|
16
10
|
raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
|
@@ -21,21 +15,42 @@ module IndieWeb
|
|
21
15
|
def results
|
22
16
|
return unless results_from_http_request
|
23
17
|
|
24
|
-
@results ||= Absolutely.
|
18
|
+
@results ||= Absolutely.to_abs(base: response.uri.to_s, relative: results_from_http_request)
|
25
19
|
rescue Absolutely::InvalidURIError => exception
|
26
20
|
raise InvalidURIError, exception
|
27
21
|
end
|
28
22
|
|
29
23
|
private
|
30
24
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
def results_from_body
|
26
|
+
LinkElementParser.new(response, self.class.identifier).results
|
27
|
+
end
|
28
|
+
|
29
|
+
def results_from_headers
|
30
|
+
LinkHeaderParser.new(response, self.class.identifier).results
|
31
|
+
end
|
32
|
+
|
33
|
+
def results_from_http_request
|
34
|
+
@results_from_http_request ||= results_from_headers || results_from_body || nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class LinkElementParser
|
39
|
+
attr_reader :identifier, :response
|
40
|
+
|
41
|
+
def initialize(response, identifier)
|
42
|
+
@response = response
|
43
|
+
@identifier = identifier
|
35
44
|
end
|
36
45
|
|
46
|
+
def results
|
47
|
+
link_element['href'] if response_is_html && link_element
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
37
52
|
def doc
|
38
|
-
@doc ||= Nokogiri::HTML(
|
53
|
+
@doc ||= Nokogiri::HTML(response.body.to_s)
|
39
54
|
end
|
40
55
|
|
41
56
|
def link_element
|
@@ -50,42 +65,59 @@ module IndieWeb
|
|
50
65
|
end
|
51
66
|
|
52
67
|
def link_elements_css_selector
|
53
|
-
@link_elements_css_selector ||= %(link[rel~="#{
|
68
|
+
@link_elements_css_selector ||= %(link[rel~="#{identifier}"][href]:not([href*="#"]))
|
54
69
|
end
|
55
70
|
|
56
|
-
def
|
57
|
-
@
|
71
|
+
def response_is_html
|
72
|
+
@response_is_html ||= response.mime_type == 'text/html'
|
58
73
|
end
|
74
|
+
end
|
59
75
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
64
80
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
@regexp_rel_paramater_pattern ||= /(?:;|\s)rel="?(?:#{REGEXP_REG_REL_TYPE_PATTERN}+\s)?#{self.class.identifier}(?:\s#{REGEXP_REG_REL_TYPE_PATTERN})?"?/
|
69
|
-
end
|
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
|
70
84
|
|
71
|
-
|
72
|
-
|
85
|
+
attr_reader :identifier, :response
|
86
|
+
|
87
|
+
def initialize(response, identifier)
|
88
|
+
@response = response
|
89
|
+
@identifier = identifier
|
73
90
|
end
|
74
91
|
|
75
|
-
def
|
92
|
+
def results
|
76
93
|
return unless link_header
|
77
94
|
|
78
|
-
endpoint_match_data = link_header.match(REGEXP_TARGET_URI_PATTERN)
|
95
|
+
endpoint_match_data = link_header.match(/#{REGEXP_TARGET_URI_PATTERN}/)
|
79
96
|
|
80
97
|
return endpoint_match_data[1] if endpoint_match_data
|
81
98
|
end
|
82
99
|
|
83
|
-
|
84
|
-
|
100
|
+
private
|
101
|
+
|
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)
|
85
106
|
end
|
86
107
|
|
87
|
-
def
|
88
|
-
@
|
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
|
116
|
+
|
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})?"?)
|
89
121
|
end
|
90
122
|
end
|
91
123
|
end
|
@@ -11,7 +11,7 @@ module IndieWeb
|
|
11
11
|
def results
|
12
12
|
return unless results_from_http_request.any?
|
13
13
|
|
14
|
-
@results ||= results_from_http_request.map { |endpoint| Absolutely.
|
14
|
+
@results ||= results_from_http_request.map { |endpoint| Absolutely.to_abs(base: response.uri.to_s, relative: endpoint) }.uniq.sort
|
15
15
|
rescue Absolutely::InvalidURIError => exception
|
16
16
|
raise InvalidURIError, exception
|
17
17
|
end
|
@@ -19,10 +19,26 @@ module IndieWeb
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def results_from_body
|
22
|
-
|
22
|
+
RedirectUriLinkElementParser.new(response, self.class.identifier).results
|
23
23
|
end
|
24
24
|
|
25
25
|
def results_from_headers
|
26
|
+
RedirectUriLinkHeaderParser.new(response, self.class.identifier).results
|
27
|
+
end
|
28
|
+
|
29
|
+
def results_from_http_request
|
30
|
+
@results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class RedirectUriLinkElementParser < LinkElementParser
|
35
|
+
def results
|
36
|
+
link_elements.map { |element| element['href'] } if response_is_html && link_elements.any?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class RedirectUriLinkHeaderParser < LinkHeaderParser
|
41
|
+
def results
|
26
42
|
return unless link_headers.any?
|
27
43
|
|
28
44
|
link_headers.map do |header|
|
@@ -31,10 +47,6 @@ module IndieWeb
|
|
31
47
|
endpoint_match_data[1] if endpoint_match_data
|
32
48
|
end
|
33
49
|
end
|
34
|
-
|
35
|
-
def results_from_http_request
|
36
|
-
@results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
|
37
|
-
end
|
38
50
|
end
|
39
51
|
end
|
40
52
|
end
|
@@ -10,6 +10,14 @@ module IndieWeb
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
+
def results_from_body
|
14
|
+
WebmentionLinkElementParser.new(response, self.class.identifier).results
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class WebmentionLinkElementParser < LinkElementParser
|
19
|
+
private
|
20
|
+
|
13
21
|
def link_element
|
14
22
|
# Return first `a` or `link` element with valid `rel` attribute
|
15
23
|
# https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
|
@@ -17,7 +25,7 @@ module IndieWeb
|
|
17
25
|
end
|
18
26
|
|
19
27
|
def link_elements_css_selector
|
20
|
-
@link_elements_css_selector ||= %([rel~="#{
|
28
|
+
@link_elements_css_selector ||= %([rel~="#{identifier}"][href]:not([href*="#"]))
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
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.
|
4
|
+
version: 0.5.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-
|
11
|
+
date: 2019-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.68.1
|
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
|
+
version: 0.68.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rubocop-performance
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '2.
|
145
|
+
version: '2.1'
|
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.
|
152
|
+
version: '2.1'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: addressable
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,7 +192,7 @@ dependencies:
|
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '1.10'
|
195
|
-
description: Discover a URL’s IndieAuth, Micropub, and Webmention endpoints.
|
195
|
+
description: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
|
196
196
|
email:
|
197
197
|
- jason@sixtwothree.org
|
198
198
|
executables: []
|
@@ -220,9 +220,11 @@ files:
|
|
220
220
|
- lib/indieweb/endpoints.rb
|
221
221
|
- lib/indieweb/endpoints/client.rb
|
222
222
|
- lib/indieweb/endpoints/exceptions.rb
|
223
|
+
- lib/indieweb/endpoints/http_request.rb
|
223
224
|
- lib/indieweb/endpoints/parsers.rb
|
224
225
|
- lib/indieweb/endpoints/parsers/authorization_endpoint_parser.rb
|
225
226
|
- lib/indieweb/endpoints/parsers/micropub_parser.rb
|
227
|
+
- lib/indieweb/endpoints/parsers/microsub_parser.rb
|
226
228
|
- lib/indieweb/endpoints/parsers/redirect_uri_parser.rb
|
227
229
|
- lib/indieweb/endpoints/parsers/token_endpoint_parser.rb
|
228
230
|
- lib/indieweb/endpoints/parsers/webmention_parser.rb
|
@@ -231,7 +233,9 @@ files:
|
|
231
233
|
homepage: https://github.com/indieweb/indieweb-endpoints-ruby
|
232
234
|
licenses:
|
233
235
|
- MIT
|
234
|
-
metadata:
|
236
|
+
metadata:
|
237
|
+
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
|
235
239
|
post_install_message:
|
236
240
|
rdoc_options: []
|
237
241
|
require_paths:
|
@@ -253,5 +257,5 @@ requirements: []
|
|
253
257
|
rubygems_version: 3.0.3
|
254
258
|
signing_key:
|
255
259
|
specification_version: 4
|
256
|
-
summary: Discover a URL’s IndieAuth, Micropub, and Webmention endpoints.
|
260
|
+
summary: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
|
257
261
|
test_files: []
|