indieweb-endpoints 3.0.0 → 4.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 +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +0 -1
- data/CHANGELOG.md +9 -0
- data/CONTRIBUTING.md +2 -2
- data/Gemfile +4 -3
- data/README.md +11 -29
- data/indieweb-endpoints.gemspec +2 -2
- data/lib/indieweb/endpoints.rb +7 -5
- data/lib/indieweb/endpoints/client.rb +36 -9
- data/lib/indieweb/endpoints/parsers/base_parser.rb +4 -2
- data/lib/indieweb/endpoints/parsers/redirect_uri_parser.rb +1 -0
- data/lib/indieweb/endpoints/parsers/webmention_parser.rb +1 -1
- data/lib/indieweb/endpoints/services/response_parser_service.rb +29 -0
- data/lib/indieweb/endpoints/version.rb +1 -1
- metadata +8 -10
- data/lib/indieweb/endpoints/services/http_request_service.rb +0 -22
- data/lib/indieweb/endpoints/services/response_body_parser_service.rb +0 -14
- data/lib/indieweb/endpoints/services/response_headers_parser_service.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c45996ba696d87124c8c764fce951197377fccfa3bf84d30ed702b3a27df610
|
4
|
+
data.tar.gz: 562c474fa0079dfc5d6cbd8286e1a8c5cb169d1f54ede4404bfab2cec854a0bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4417010c2a25d2bb07f8e59f63cd3aa31149aaa5dda33391fba11b7ef1d90d1acb2cd8e642dcf38086a6016027159914941d8dd69fb7f9beae7fe30b6b1cc2db
|
7
|
+
data.tar.gz: 43da9e43bb391e7e2ecf999d1bb21dd3776c005037a746230d65066c67dad68883f1397fa2e46c812daec21bd80df006e24620a4608e06774787d08705b81981
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 4.0.0 / 2020-07-21
|
4
|
+
|
5
|
+
- **Breaking change:** Return a Hash of endpoints instead of an OpenStruct (15dc387)
|
6
|
+
- Update [link-header-parser](https://rubygems.org/gems/link-header-parser) dependency to v2.0.0 (2255e6b)
|
7
|
+
- **Breaking change:** Update development Ruby version to 2.5.8 and minimum Ruby version to 2.5 (dd5a142)
|
8
|
+
- Refactor response headers/body parsers into a single class (ee02da3)
|
9
|
+
- Refactor `IndieWeb::Endpoints::Client` and remove `HttpRequestService` (2732616)
|
10
|
+
- Add offending url to exception message (#5) (4bf7a54)
|
11
|
+
|
3
12
|
## 3.0.0 / 2020-05-14
|
4
13
|
|
5
14
|
- Update Absolutely and LinkHeaderParser dependencies (9e0a64a)
|
data/CONTRIBUTING.md
CHANGED
@@ -8,9 +8,9 @@ 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.
|
11
|
+
indieweb-endpoints-ruby is developed using Ruby 2.5.8 and is additionally tested against Ruby 2.6 and 2.7 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
|
12
12
|
|
13
|
-
Before making changes to indieweb-endpoints-ruby, you'll want to install Ruby 2.
|
13
|
+
Before making changes to indieweb-endpoints-ruby, you'll want to install Ruby 2.5.8. 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.5.8 using your method of choice, install the project's gems by running:
|
14
14
|
|
15
15
|
```sh
|
16
16
|
bundle install
|
data/Gemfile
CHANGED
@@ -3,12 +3,13 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in indieweb-endpoints.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
gem 'pry-byebug', '~> 3.9'
|
6
7
|
gem 'rake', '~> 13.0'
|
7
8
|
gem 'reek', '~> 6.0'
|
8
9
|
gem 'rspec', '~> 3.9'
|
9
|
-
gem 'rubocop', '~> 0.
|
10
|
-
gem 'rubocop-performance', '~> 1.
|
11
|
-
gem 'rubocop-rspec', '~> 1.
|
10
|
+
gem 'rubocop', '~> 0.88.0'
|
11
|
+
gem 'rubocop-performance', '~> 1.7'
|
12
|
+
gem 'rubocop-rspec', '~> 1.42'
|
12
13
|
gem 'simplecov', '~> 0.18.5'
|
13
14
|
gem 'simplecov-console', '~> 0.7.2'
|
14
15
|
gem 'webmock', '~> 3.8'
|
data/README.md
CHANGED
@@ -12,13 +12,13 @@
|
|
12
12
|
|
13
13
|
- Compliant with [Section 4.1](https://www.w3.org/TR/indieauth/#discovery-by-clients) and [Section 4.2.2](https://www.w3.org/TR/indieauth/#redirect-url) of [the W3C's IndieAuth Working Group Note](https://www.w3.org/TR/indieauth/), [Section 5.3](https://www.w3.org/TR/micropub/#endpoint-discovery) of [the W3C's Micropub Recommendation](https://www.w3.org/TR/micropub/), and [Section 3.1.2](https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint) of [the W3C's Webmention Recommendation](https://www.w3.org/TR/webmention/).
|
14
14
|
- Passes all Endpoint Discovery tests on [webmention.rocks](https://webmention.rocks).
|
15
|
-
- Supports Ruby 2.
|
15
|
+
- Supports Ruby 2.5 and newer.
|
16
16
|
|
17
17
|
## Getting Started
|
18
18
|
|
19
|
-
Before installing and using indieweb-endpoints-ruby, you'll want to have [Ruby](https://www.ruby-lang.org) 2.
|
19
|
+
Before installing and using indieweb-endpoints-ruby, you'll want to have [Ruby](https://www.ruby-lang.org) 2.5 (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.
|
21
|
+
indieweb-endpoints-ruby is developed using Ruby 2.5.8 and is additionally tested against Ruby 2.6 and 2.7 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
|
22
22
|
|
23
23
|
## Installation
|
24
24
|
|
@@ -45,25 +45,11 @@ With indieweb-endpoints-ruby added to your project's `Gemfile` and installed, yo
|
|
45
45
|
```ruby
|
46
46
|
require 'indieweb/endpoints'
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
puts endpoints # => #<OpenStruct authorization_endpoint="https://aaronparecki.com/auth", micropub="https://aaronparecki.com/micropub", microsub="https://aperture.p3k.io/microsub/1", redirect_uri=nil, token_endpoint="https://aaronparecki.com/auth/token", webmention="https://webmention.io/aaronpk/webmention">
|
51
|
-
```
|
52
|
-
|
53
|
-
This example will search `https://aaronparecki.com` for valid IndieAuth, Micropub, and Webmention endpoints. In this case, the program returns an `OpenStruct` with the following attributes (represented below as a `Hash`):
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
{
|
57
|
-
authorization_endpoint: 'https://aaronparecki.com/auth',
|
58
|
-
micropub: 'https://aaronparecki.com/micropub',
|
59
|
-
microsub: 'https://aperture.p3k.io/microsub/1',
|
60
|
-
redirect_uri: nil,
|
61
|
-
token_endpoint: 'https://aaronparecki.com/auth/token',
|
62
|
-
webmention: 'https://webmention.io/aaronpk/webmention'
|
63
|
-
}
|
48
|
+
IndieWeb::Endpoints.get('https://aaronparecki.com')
|
49
|
+
#=> { authorization_endpoint: "https://aaronparecki.com/auth", micropub: "https://aaronparecki.com/micropub", microsub: "https://aperture.p3k.io/microsub/1", redirect_uri: nil, token_endpoint: "https://aaronparecki.com/auth/token", webmention: "https://webmention.io/aaronpk/webmention" }
|
64
50
|
```
|
65
51
|
|
66
|
-
|
52
|
+
This example will search `https://aaronparecki.com` for valid IndieAuth, Micropub, and Webmention endpoints and return a `Hash` of results. Each key in the returned `Hash` will have a value of either a `String` representing a URL or `nil`. The `redirect_uri` key's value will be either an `Array` or `nil` since a given URL may register multiple callback URLs.
|
67
53
|
|
68
54
|
### Advanced Usage
|
69
55
|
|
@@ -73,17 +59,13 @@ Should the need arise, you may work with the `IndieWeb::Endpoints::Client` class
|
|
73
59
|
require 'indieweb/endpoints'
|
74
60
|
|
75
61
|
client = IndieWeb::Endpoints::Client.new('https://aaronparecki.com')
|
62
|
+
#=> #<IndieWeb::Endpoints::Client url: "https://aaronparecki.com">
|
76
63
|
|
77
|
-
|
78
|
-
|
79
|
-
endpoints = client.endpoints
|
64
|
+
client.response
|
65
|
+
#=> #<HTTP::Response/1.1 200 OK {…}>
|
80
66
|
|
81
|
-
|
82
|
-
|
83
|
-
puts endpoints.microsub # => 'https://aperture.p3k.io/microsub/1'
|
84
|
-
puts endpoints.redirect_uri # => nil
|
85
|
-
puts endpoints.token_endpoint # => 'https://aaronparecki.com/auth/token'
|
86
|
-
puts endpoints.webmention # => 'https://webmention.io/aaronpk/webmention'
|
67
|
+
client.endpoints
|
68
|
+
#=> { authorization_endpoint: "https://aaronparecki.com/auth", micropub: "https://aaronparecki.com/micropub", microsub: "https://aperture.p3k.io/microsub/1", redirect_uri: nil, token_endpoint: "https://aaronparecki.com/auth/token", webmention: "https://webmention.io/aaronpk/webmention" }
|
87
69
|
```
|
88
70
|
|
89
71
|
### Exception Handling
|
data/indieweb-endpoints.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative 'lib/indieweb/endpoints/version'
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
4
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5', '< 2.8')
|
5
5
|
|
6
6
|
spec.name = 'indieweb-endpoints'
|
7
7
|
spec.version = IndieWeb::Endpoints::VERSION
|
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency 'absolutely', '~> 4.0'
|
26
26
|
spec.add_runtime_dependency 'addressable', '~> 2.7'
|
27
27
|
spec.add_runtime_dependency 'http', '~> 4.4'
|
28
|
-
spec.add_runtime_dependency 'link-header-parser', '~>
|
28
|
+
spec.add_runtime_dependency 'link-header-parser', '~> 2.0'
|
29
29
|
spec.add_runtime_dependency 'nokogiri', '~> 1.10'
|
30
30
|
end
|
data/lib/indieweb/endpoints.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
1
|
require 'absolutely'
|
4
2
|
require 'addressable/uri'
|
5
3
|
require 'http'
|
@@ -9,9 +7,7 @@ require 'nokogiri'
|
|
9
7
|
require 'indieweb/endpoints/version'
|
10
8
|
require 'indieweb/endpoints/exceptions'
|
11
9
|
|
12
|
-
require 'indieweb/endpoints/services/
|
13
|
-
require 'indieweb/endpoints/services/response_body_parser_service'
|
14
|
-
require 'indieweb/endpoints/services/response_headers_parser_service'
|
10
|
+
require 'indieweb/endpoints/services/response_parser_service'
|
15
11
|
|
16
12
|
require 'indieweb/endpoints/client'
|
17
13
|
require 'indieweb/endpoints/parsers'
|
@@ -26,6 +22,12 @@ require 'indieweb/endpoints/parsers/webmention_parser'
|
|
26
22
|
|
27
23
|
module IndieWeb
|
28
24
|
module Endpoints
|
25
|
+
# Discover a URL's IndieAuth, Micropub, Microsub, and Webmention endpoints
|
26
|
+
#
|
27
|
+
# IndieWeb::Endpoints.get('https://aaronparecki.com')
|
28
|
+
#
|
29
|
+
# @param url [String] an absolute URL
|
30
|
+
# @return [Hash{Symbol => String, Array, nil}]
|
29
31
|
def self.get(url)
|
30
32
|
Client.new(url).endpoints
|
31
33
|
end
|
@@ -1,27 +1,54 @@
|
|
1
1
|
module IndieWeb
|
2
2
|
module Endpoints
|
3
3
|
class Client
|
4
|
+
HTTP_HEADERS_OPTS = {
|
5
|
+
accept: '*/*',
|
6
|
+
user_agent: 'IndieWeb Endpoint Discovery (https://rubygems.org/gems/indieweb-endpoints)'
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
# Create a new client with a URL to parse for IndieWeb endpoints
|
10
|
+
#
|
11
|
+
# client = IndieWeb::Endpoints::Client.new('https://aaronparecki.com')
|
12
|
+
#
|
13
|
+
# @param url [String] an absolute URL
|
4
14
|
def initialize(url)
|
5
|
-
|
15
|
+
raise ArgumentError, "url must be a String (given #{url.class})" unless url.is_a?(String)
|
6
16
|
|
7
|
-
|
8
|
-
|
9
|
-
raise
|
10
|
-
|
11
|
-
|
17
|
+
@url = url
|
18
|
+
|
19
|
+
raise ArgumentError, "url (#{url}) must be an absolute URL (e.g. https://example.com)" unless uri.absolute? && uri.scheme.match?(/^https?$/)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
def inspect
|
24
|
+
format(%(#<#{self.class.name}:%#0x url: #{url.inspect}>), object_id)
|
12
25
|
end
|
13
26
|
|
27
|
+
# @return [Hash{Symbol => String, Array, nil}]
|
14
28
|
def endpoints
|
15
|
-
@endpoints ||=
|
29
|
+
@endpoints ||= Parsers.registered.transform_values { |parser| parser.new(response).results }
|
16
30
|
end
|
17
31
|
|
32
|
+
# @see https://www.w3.org/TR/webmention/#limits-on-get-requests
|
33
|
+
#
|
34
|
+
# @return [HTTP::Response]
|
18
35
|
def response
|
19
|
-
@response ||=
|
36
|
+
@response ||= HTTP.follow(max_hops: 20).headers(HTTP_HEADERS_OPTS).timeout(connect: 5, read: 5).get(uri)
|
37
|
+
rescue HTTP::ConnectionError,
|
38
|
+
HTTP::TimeoutError,
|
39
|
+
HTTP::Redirector::TooManyRedirectsError => exception
|
40
|
+
raise IndieWeb::Endpoints.const_get(exception.class.name.split('::').last), exception
|
20
41
|
end
|
21
42
|
|
22
43
|
private
|
23
44
|
|
24
|
-
attr_accessor :
|
45
|
+
attr_accessor :url
|
46
|
+
|
47
|
+
def uri
|
48
|
+
@uri ||= Addressable::URI.parse(url)
|
49
|
+
rescue Addressable::URI::InvalidURIError => exception
|
50
|
+
raise InvalidURIError, exception
|
51
|
+
end
|
25
52
|
end
|
26
53
|
end
|
27
54
|
end
|
@@ -6,12 +6,14 @@ module IndieWeb
|
|
6
6
|
attr_reader :identifier
|
7
7
|
end
|
8
8
|
|
9
|
+
# @param response [HTTP::Response]
|
9
10
|
def initialize(response)
|
10
11
|
raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
|
11
12
|
|
12
13
|
@response = response
|
13
14
|
end
|
14
15
|
|
16
|
+
# @return [String]
|
15
17
|
def results
|
16
18
|
mapped_results.shift
|
17
19
|
end
|
@@ -27,11 +29,11 @@ module IndieWeb
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def results_from_body
|
30
|
-
@results_from_body ||= Services::
|
32
|
+
@results_from_body ||= Services::ResponseParserService.parse_body(response, self.class.identifier)
|
31
33
|
end
|
32
34
|
|
33
35
|
def results_from_headers
|
34
|
-
@results_from_headers ||= Services::
|
36
|
+
@results_from_headers ||= Services::ResponseParserService.parse_headers(response, self.class.identifier)
|
35
37
|
end
|
36
38
|
|
37
39
|
def results_from_http_request
|
@@ -9,7 +9,7 @@ module IndieWeb
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def results_for_node(node)
|
12
|
-
Services::
|
12
|
+
Services::ResponseParserService.parse_body(response, self.class.identifier, node)
|
13
13
|
end
|
14
14
|
|
15
15
|
# https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module IndieWeb
|
2
|
+
module Endpoints
|
3
|
+
module Services
|
4
|
+
class ResponseParserService
|
5
|
+
# @param response [HTTP::Response]
|
6
|
+
# @param identifier [Symbol]
|
7
|
+
# @return [Array<String>]
|
8
|
+
def self.parse_body(response, identifier, node = 'link')
|
9
|
+
return unless response.mime_type == 'text/html'
|
10
|
+
|
11
|
+
# Reject endpoints that contain a fragment identifier
|
12
|
+
Nokogiri::HTML(response.body.to_s).css(%(#{node}[rel~="#{identifier}"][href]:not([href*="#"]))).map { |element| element['href'] }
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param response [HTTP::Response]
|
16
|
+
# @param identifier [Symbol]
|
17
|
+
# @return [Array<String>, nil]
|
18
|
+
def self.parse_headers(response, identifier)
|
19
|
+
headers = LinkHeaderParser.parse(response.headers.get('link'), base: response.uri.to_s).group_by_relation_type[identifier]
|
20
|
+
|
21
|
+
return unless headers
|
22
|
+
|
23
|
+
# Reject endpoints that contain a fragment identifier
|
24
|
+
headers.reject { |header| Addressable::URI.parse(header.target_uri).fragment }.map(&:target_uri)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
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:
|
4
|
+
version: 4.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: 2020-
|
11
|
+
date: 2020-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: absolutely
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '2.0'
|
62
62
|
type: :runtime
|
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:
|
68
|
+
version: '2.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,16 +116,14 @@ files:
|
|
116
116
|
- lib/indieweb/endpoints/parsers/redirect_uri_parser.rb
|
117
117
|
- lib/indieweb/endpoints/parsers/token_endpoint_parser.rb
|
118
118
|
- lib/indieweb/endpoints/parsers/webmention_parser.rb
|
119
|
-
- lib/indieweb/endpoints/services/
|
120
|
-
- lib/indieweb/endpoints/services/response_body_parser_service.rb
|
121
|
-
- lib/indieweb/endpoints/services/response_headers_parser_service.rb
|
119
|
+
- lib/indieweb/endpoints/services/response_parser_service.rb
|
122
120
|
- lib/indieweb/endpoints/version.rb
|
123
121
|
homepage: https://github.com/indieweb/indieweb-endpoints-ruby
|
124
122
|
licenses:
|
125
123
|
- MIT
|
126
124
|
metadata:
|
127
125
|
bug_tracker_uri: https://github.com/indieweb/indieweb-endpoints-ruby/issues
|
128
|
-
changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/
|
126
|
+
changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v4.0.0/CHANGELOG.md
|
129
127
|
post_install_message:
|
130
128
|
rdoc_options: []
|
131
129
|
require_paths:
|
@@ -134,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
132
|
requirements:
|
135
133
|
- - ">="
|
136
134
|
- !ruby/object:Gem::Version
|
137
|
-
version: '2.
|
135
|
+
version: '2.5'
|
138
136
|
- - "<"
|
139
137
|
- !ruby/object:Gem::Version
|
140
138
|
version: '2.8'
|
@@ -144,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
142
|
- !ruby/object:Gem::Version
|
145
143
|
version: '0'
|
146
144
|
requirements: []
|
147
|
-
rubygems_version: 3.1.
|
145
|
+
rubygems_version: 3.1.2
|
148
146
|
signing_key:
|
149
147
|
specification_version: 4
|
150
148
|
summary: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module IndieWeb
|
2
|
-
module Endpoints
|
3
|
-
module Services
|
4
|
-
class HttpRequestService
|
5
|
-
HTTP_HEADERS_OPTS = {
|
6
|
-
accept: '*/*',
|
7
|
-
user_agent: 'IndieWeb Endpoint Discovery (https://rubygems.org/gems/indieweb-endpoints)'
|
8
|
-
}.freeze
|
9
|
-
|
10
|
-
# HTTP options derived from Webmention specification examples
|
11
|
-
# https://www.w3.org/TR/webmention/#limits-on-get-requests
|
12
|
-
def self.get(uri)
|
13
|
-
HTTP.follow(max_hops: 20).headers(HTTP_HEADERS_OPTS).timeout(connect: 5, read: 5).get(uri)
|
14
|
-
rescue HTTP::ConnectionError,
|
15
|
-
HTTP::TimeoutError,
|
16
|
-
HTTP::Redirector::TooManyRedirectsError => exception
|
17
|
-
raise IndieWeb::Endpoints.const_get(exception.class.name.split('::').last), exception
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module IndieWeb
|
2
|
-
module Endpoints
|
3
|
-
module Services
|
4
|
-
class ResponseBodyParserService
|
5
|
-
def self.parse(response, identifier, node = 'link')
|
6
|
-
return unless response.mime_type == 'text/html'
|
7
|
-
|
8
|
-
# Reject endpoints that contain a fragment identifier
|
9
|
-
Nokogiri::HTML(response.body.to_s).css(%(#{node}[rel~="#{identifier}"][href]:not([href*="#"]))).map { |element| element['href'] }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module IndieWeb
|
2
|
-
module Endpoints
|
3
|
-
module Services
|
4
|
-
class ResponseHeadersParserService
|
5
|
-
def self.parse(response, identifier)
|
6
|
-
headers = LinkHeaderParser.parse(response.headers.get('link'), base: response.uri.to_s).by_relation_type[identifier]
|
7
|
-
|
8
|
-
return unless headers
|
9
|
-
|
10
|
-
# Reject endpoints that contain a fragment identifier
|
11
|
-
headers.reject { |header| Addressable::URI.parse(header.target_uri).fragment }.map(&:target_uri)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|