indieweb-endpoints 1.0.2 → 5.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/.reek.yml +0 -5
- data/.rubocop.yml +5 -6
- data/.ruby-version +1 -1
- data/.simplecov +2 -0
- data/.travis.yml +3 -6
- data/CHANGELOG.md +28 -0
- data/CONTRIBUTING.md +2 -2
- data/Gemfile +11 -0
- data/README.md +13 -31
- data/indieweb-endpoints.gemspec +10 -23
- data/lib/indieweb/endpoints.rb +8 -7
- data/lib/indieweb/endpoints/client.rb +36 -9
- data/lib/indieweb/endpoints/parsers.rb +5 -33
- data/lib/indieweb/endpoints/parsers/authorization_endpoint_parser.rb +1 -3
- data/lib/indieweb/endpoints/parsers/base_parser.rb +45 -0
- data/lib/indieweb/endpoints/parsers/micropub_parser.rb +1 -3
- data/lib/indieweb/endpoints/parsers/microsub_parser.rb +1 -3
- data/lib/indieweb/endpoints/parsers/redirect_uri_parser.rb +2 -3
- data/lib/indieweb/endpoints/parsers/token_endpoint_parser.rb +1 -3
- data/lib/indieweb/endpoints/parsers/webmention_parser.rb +2 -4
- data/lib/indieweb/endpoints/services/response_parser_service.rb +29 -0
- data/lib/indieweb/endpoints/version.rb +1 -1
- metadata +17 -145
- data/lib/indieweb/endpoints/concerns/registerable.rb +0 -15
- data/lib/indieweb/endpoints/services/http_request_service.rb +0 -39
- 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: f89e56b8a2f2bac61305a9d0012bdd54f4f2623b539ea19f58e0d81b6af1a966
|
4
|
+
data.tar.gz: 3f0e860760e5bed119e2be2cbc40dc235a179b53a880f9a2f0a4efada8e6b739
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47f6d68cb1894fee56ee0f23d3caf90c5bd143980a52085dff2a35b37467c0e6a222e2eea926b6cb904437f4b196f75bf5051cf5a47e09bfb262da4b2bc04fdb
|
7
|
+
data.tar.gz: '0891cbfb3831d7a2b85e9b7b3068c3679a1e9a86938e4237e1ab3f10c6760b6a5f8ff0c92456bb52314802a4c42551c936973e8956fa85a39cdc8543ef7e0420'
|
data/.reek.yml
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
detectors:
|
2
2
|
IrresponsibleModule:
|
3
3
|
enabled: false
|
4
|
-
UtilityFunction:
|
5
|
-
exclude:
|
6
|
-
- FixtureHelpers#read_fixture
|
7
|
-
- IndieWeb::Endpoints::Services::ResponseBodyParserService#parse
|
8
|
-
- IndieWeb::Endpoints::Services::ResponseHeadersParserService#parse
|
9
4
|
|
10
5
|
exclude_paths:
|
11
6
|
- vendor/
|
data/.rubocop.yml
CHANGED
@@ -2,17 +2,16 @@ require:
|
|
2
2
|
- rubocop-performance
|
3
3
|
- rubocop-rspec
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
AllCops:
|
6
|
+
NewCops: enable
|
7
|
+
|
8
|
+
Layout/LineLength:
|
9
|
+
Enabled: false
|
7
10
|
|
8
11
|
Metrics/BlockLength:
|
9
12
|
Exclude:
|
10
|
-
- indieweb-endpoints.gemspec
|
11
13
|
- spec/**/*.rb
|
12
14
|
|
13
|
-
Metrics/LineLength:
|
14
|
-
Enabled: false
|
15
|
-
|
16
15
|
Naming/RescuedExceptionsVariableName:
|
17
16
|
PreferredName: exception
|
18
17
|
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.8
|
data/.simplecov
CHANGED
@@ -2,9 +2,11 @@ require 'simplecov-console'
|
|
2
2
|
|
3
3
|
formatters = [SimpleCov::Formatter::HTMLFormatter]
|
4
4
|
|
5
|
+
# rubocop:disable Style/IfUnlessModifier
|
5
6
|
if RSpec.configuration.files_to_run.length > 1
|
6
7
|
formatters << SimpleCov::Formatter::Console
|
7
8
|
end
|
9
|
+
# rubocop:enable Style/IfUnlessModifier
|
8
10
|
|
9
11
|
SimpleCov.start do
|
10
12
|
formatter SimpleCov::Formatter::MultiFormatter.new(formatters)
|
data/.travis.yml
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
+
dist: bionic
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
|
-
- 2.4
|
4
4
|
- 2.5
|
5
5
|
- 2.6
|
6
|
-
|
7
|
-
|
8
|
-
before_install:
|
9
|
-
- gem update --system
|
10
|
-
- gem install bundler
|
6
|
+
- 2.7
|
7
|
+
cache: bundler
|
11
8
|
before_script:
|
12
9
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
10
|
- chmod +x ./cc-test-reporter
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 5.0.0 / 2020-11-11
|
4
|
+
|
5
|
+
- Update absolutely and link-header-parser dependencies (064696e)
|
6
|
+
|
7
|
+
## 4.0.0 / 2020-07-21
|
8
|
+
|
9
|
+
- **Breaking change:** Return a Hash of endpoints instead of an OpenStruct (15dc387)
|
10
|
+
- Update [link-header-parser](https://rubygems.org/gems/link-header-parser) dependency to v2.0.0 (2255e6b)
|
11
|
+
- **Breaking change:** Update development Ruby version to 2.5.8 and minimum Ruby version to 2.5 (dd5a142)
|
12
|
+
- Refactor response headers/body parsers into a single class (ee02da3)
|
13
|
+
- Refactor `IndieWeb::Endpoints::Client` and remove `HttpRequestService` (2732616)
|
14
|
+
- Add offending url to exception message (#5) (4bf7a54)
|
15
|
+
|
16
|
+
## 3.0.0 / 2020-05-14
|
17
|
+
|
18
|
+
- Update Absolutely and LinkHeaderParser dependencies (9e0a64a)
|
19
|
+
- Move development dependencies to `Gemfile` (67067f3)
|
20
|
+
- Update development Ruby version to 2.4.10 (f5430f9)
|
21
|
+
|
22
|
+
## 2.0.0 / 2020-01-25
|
23
|
+
|
24
|
+
- Downgrade HTTP gem version constraint to ~> 4.3 (cb63230)
|
25
|
+
|
26
|
+
## 1.1.0 / 2020-01-20
|
27
|
+
|
28
|
+
- Expand supported Ruby versions to include 2.7 (ae63ed0)
|
29
|
+
- Update project Ruby version to 2.4.9 (e576ad6)
|
30
|
+
|
3
31
|
## 1.0.2 / 2019-08-31
|
4
32
|
|
5
33
|
- Update WebMock and Addressable gems (298da63)
|
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
@@ -2,3 +2,14 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in indieweb-endpoints.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem 'pry-byebug', '~> 3.9'
|
7
|
+
gem 'rake', '~> 13.0'
|
8
|
+
gem 'reek', '~> 6.0'
|
9
|
+
gem 'rspec', '~> 3.10'
|
10
|
+
gem 'rubocop', '~> 1.2'
|
11
|
+
gem 'rubocop-performance', '~> 1.8'
|
12
|
+
gem 'rubocop-rspec', '~> 2.0'
|
13
|
+
gem 'simplecov', '~> 0.19.1'
|
14
|
+
gem 'simplecov-console', '~> 0.8.0'
|
15
|
+
gem 'webmock', '~> 3.9'
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[](https://rubygems.org/gems/indieweb-endpoints)
|
6
6
|
[](https://rubygems.org/gems/indieweb-endpoints)
|
7
|
-
[](https://travis-ci.com/indieweb/indieweb-endpoints-ruby)
|
8
8
|
[](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby)
|
9
9
|
[](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby/code)
|
10
10
|
|
@@ -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
|
@@ -102,7 +84,7 @@ From [httprb/http](https://github.com/httprb/http):
|
|
102
84
|
|
103
85
|
## Contributing
|
104
86
|
|
105
|
-
Interested in helping improve indieweb-endpoints-ruby? Awesome! Your help is greatly appreciated. See [CONTRIBUTING.md](https://github.com/indieweb/indieweb-endpoints-ruby/blob/
|
87
|
+
Interested in helping improve indieweb-endpoints-ruby? Awesome! Your help is greatly appreciated. See [CONTRIBUTING.md](https://github.com/indieweb/indieweb-endpoints-ruby/blob/main/CONTRIBUTING.md) for details.
|
106
88
|
|
107
89
|
By contributing to and participating in the development of indieweb-endpoints-ruby, you acknowledge that you have read and agree to the [IndieWeb Code of Conduct](https://indieweb.org/code-of-conduct).
|
108
90
|
|
data/indieweb-endpoints.gemspec
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
|
4
|
-
require 'indieweb/endpoints/version'
|
1
|
+
require_relative 'lib/indieweb/endpoints/version'
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
|
-
spec.required_ruby_version =
|
4
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5', '< 2.8')
|
8
5
|
|
9
6
|
spec.name = 'indieweb-endpoints'
|
10
7
|
spec.version = IndieWeb::Endpoints::VERSION
|
@@ -16,28 +13,18 @@ Gem::Specification.new do |spec|
|
|
16
13
|
spec.homepage = 'https://github.com/indieweb/indieweb-endpoints-ruby'
|
17
14
|
spec.license = 'MIT'
|
18
15
|
|
19
|
-
spec.files =
|
16
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(bin|spec)/}) }
|
18
|
+
end
|
20
19
|
|
21
20
|
spec.require_paths = ['lib']
|
22
21
|
|
23
|
-
spec.metadata = {
|
24
|
-
|
25
|
-
'changelog_uri' => "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
|
26
|
-
}
|
27
|
-
|
28
|
-
spec.add_development_dependency 'rake', '~> 12.3'
|
29
|
-
spec.add_development_dependency 'reek', '~> 5.4'
|
30
|
-
spec.add_development_dependency 'rspec', '~> 3.8'
|
31
|
-
spec.add_development_dependency 'rubocop', '~> 0.74.0'
|
32
|
-
spec.add_development_dependency 'rubocop-performance', '~> 1.4'
|
33
|
-
spec.add_development_dependency 'rubocop-rspec', '~> 1.35'
|
34
|
-
spec.add_development_dependency 'simplecov', '~> 0.17.0'
|
35
|
-
spec.add_development_dependency 'simplecov-console', '~> 0.5.0'
|
36
|
-
spec.add_development_dependency 'webmock', '~> 3.7'
|
22
|
+
spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
|
23
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
|
37
24
|
|
38
|
-
spec.add_runtime_dependency 'absolutely', '~>
|
25
|
+
spec.add_runtime_dependency 'absolutely', '~> 5.0'
|
39
26
|
spec.add_runtime_dependency 'addressable', '~> 2.7'
|
40
|
-
spec.add_runtime_dependency 'http', '~>
|
41
|
-
spec.add_runtime_dependency 'link-header-parser', '~>
|
27
|
+
spec.add_runtime_dependency 'http', '~> 4.4'
|
28
|
+
spec.add_runtime_dependency 'link-header-parser', '~> 2.1'
|
42
29
|
spec.add_runtime_dependency 'nokogiri', '~> 1.10'
|
43
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,15 +7,12 @@ require 'nokogiri'
|
|
9
7
|
require 'indieweb/endpoints/version'
|
10
8
|
require 'indieweb/endpoints/exceptions'
|
11
9
|
|
12
|
-
require 'indieweb/endpoints/
|
13
|
-
|
14
|
-
require 'indieweb/endpoints/services/http_request_service'
|
15
|
-
require 'indieweb/endpoints/services/response_body_parser_service'
|
16
|
-
require 'indieweb/endpoints/services/response_headers_parser_service'
|
10
|
+
require 'indieweb/endpoints/services/response_parser_service'
|
17
11
|
|
18
12
|
require 'indieweb/endpoints/client'
|
19
13
|
require 'indieweb/endpoints/parsers'
|
20
14
|
|
15
|
+
require 'indieweb/endpoints/parsers/base_parser'
|
21
16
|
require 'indieweb/endpoints/parsers/authorization_endpoint_parser'
|
22
17
|
require 'indieweb/endpoints/parsers/micropub_parser'
|
23
18
|
require 'indieweb/endpoints/parsers/microsub_parser'
|
@@ -27,6 +22,12 @@ require 'indieweb/endpoints/parsers/webmention_parser'
|
|
27
22
|
|
28
23
|
module IndieWeb
|
29
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}]
|
30
31
|
def self.get(url)
|
31
32
|
Client.new(url).endpoints
|
32
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
|
@@ -1,40 +1,12 @@
|
|
1
1
|
module IndieWeb
|
2
2
|
module Endpoints
|
3
3
|
module Parsers
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(response)
|
8
|
-
raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
|
9
|
-
|
10
|
-
@response = response
|
11
|
-
end
|
12
|
-
|
13
|
-
def results
|
14
|
-
mapped_results.shift
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
attr_reader :response
|
20
|
-
|
21
|
-
def mapped_results
|
22
|
-
@mapped_results ||= results_from_http_request.map { |endpoint| Absolutely.to_abs(base: response.uri.to_s, relative: endpoint) }.uniq.sort
|
23
|
-
rescue Absolutely::InvalidURIError => exception
|
24
|
-
raise InvalidURIError, exception
|
25
|
-
end
|
26
|
-
|
27
|
-
def results_from_body
|
28
|
-
@results_from_body ||= Services::ResponseBodyParserService.new.parse(response, self.class.identifier)
|
29
|
-
end
|
30
|
-
|
31
|
-
def results_from_headers
|
32
|
-
@results_from_headers ||= Services::ResponseHeadersParserService.new.parse(response, self.class.identifier)
|
33
|
-
end
|
4
|
+
def self.register(klass)
|
5
|
+
registered[klass.identifier] = klass
|
6
|
+
end
|
34
7
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
8
|
+
def self.registered
|
9
|
+
@registered ||= {}
|
38
10
|
end
|
39
11
|
end
|
40
12
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module IndieWeb
|
2
|
+
module Endpoints
|
3
|
+
module Parsers
|
4
|
+
class BaseParser
|
5
|
+
class << self
|
6
|
+
attr_reader :identifier
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param response [HTTP::Response]
|
10
|
+
def initialize(response)
|
11
|
+
raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
|
12
|
+
|
13
|
+
@response = response
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [String]
|
17
|
+
def results
|
18
|
+
mapped_results.shift
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :response
|
24
|
+
|
25
|
+
def mapped_results
|
26
|
+
@mapped_results ||= results_from_http_request.map { |endpoint| Absolutely.to_abs(base: response.uri.to_s, relative: endpoint) }.uniq.sort
|
27
|
+
rescue Absolutely::InvalidURIError => exception
|
28
|
+
raise InvalidURIError, exception
|
29
|
+
end
|
30
|
+
|
31
|
+
def results_from_body
|
32
|
+
@results_from_body ||= Services::ResponseParserService.parse_body(response, self.class.identifier)
|
33
|
+
end
|
34
|
+
|
35
|
+
def results_from_headers
|
36
|
+
@results_from_headers ||= Services::ResponseParserService.parse_headers(response, self.class.identifier)
|
37
|
+
end
|
38
|
+
|
39
|
+
def results_from_http_request
|
40
|
+
@results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -2,12 +2,11 @@ module IndieWeb
|
|
2
2
|
module Endpoints
|
3
3
|
module Parsers
|
4
4
|
class RedirectUriParser < BaseParser
|
5
|
-
|
6
|
-
:redirect_uri
|
7
|
-
end
|
5
|
+
@identifier = :redirect_uri
|
8
6
|
|
9
7
|
Parsers.register(self)
|
10
8
|
|
9
|
+
# @return [Array<String>, nil]
|
11
10
|
def results
|
12
11
|
return unless mapped_results.any?
|
13
12
|
|
@@ -2,16 +2,14 @@ module IndieWeb
|
|
2
2
|
module Endpoints
|
3
3
|
module Parsers
|
4
4
|
class WebmentionParser < BaseParser
|
5
|
-
|
6
|
-
:webmention
|
7
|
-
end
|
5
|
+
@identifier = :webmention
|
8
6
|
|
9
7
|
Parsers.register(self)
|
10
8
|
|
11
9
|
private
|
12
10
|
|
13
11
|
def results_for_node(node)
|
14
|
-
Services::
|
12
|
+
Services::ResponseParserService.parse_body(response, self.class.identifier, node)
|
15
13
|
end
|
16
14
|
|
17
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,155 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: indieweb-endpoints
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Garber
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rake
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '12.3'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '12.3'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: reek
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '5.4'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '5.4'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '3.8'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '3.8'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rubocop
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.74.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.74.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rubocop-performance
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.4'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.4'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop-rspec
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.35'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.35'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: simplecov
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.17.0
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.17.0
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov-console
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.5.0
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.5.0
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: webmock
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '3.7'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '3.7'
|
139
13
|
- !ruby/object:Gem::Dependency
|
140
14
|
name: absolutely
|
141
15
|
requirement: !ruby/object:Gem::Requirement
|
142
16
|
requirements:
|
143
17
|
- - "~>"
|
144
18
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
19
|
+
version: '5.0'
|
146
20
|
type: :runtime
|
147
21
|
prerelease: false
|
148
22
|
version_requirements: !ruby/object:Gem::Requirement
|
149
23
|
requirements:
|
150
24
|
- - "~>"
|
151
25
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
26
|
+
version: '5.0'
|
153
27
|
- !ruby/object:Gem::Dependency
|
154
28
|
name: addressable
|
155
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,28 +44,28 @@ dependencies:
|
|
170
44
|
requirements:
|
171
45
|
- - "~>"
|
172
46
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
47
|
+
version: '4.4'
|
174
48
|
type: :runtime
|
175
49
|
prerelease: false
|
176
50
|
version_requirements: !ruby/object:Gem::Requirement
|
177
51
|
requirements:
|
178
52
|
- - "~>"
|
179
53
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
54
|
+
version: '4.4'
|
181
55
|
- !ruby/object:Gem::Dependency
|
182
56
|
name: link-header-parser
|
183
57
|
requirement: !ruby/object:Gem::Requirement
|
184
58
|
requirements:
|
185
59
|
- - "~>"
|
186
60
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
61
|
+
version: '2.1'
|
188
62
|
type: :runtime
|
189
63
|
prerelease: false
|
190
64
|
version_requirements: !ruby/object:Gem::Requirement
|
191
65
|
requirements:
|
192
66
|
- - "~>"
|
193
67
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
68
|
+
version: '2.1'
|
195
69
|
- !ruby/object:Gem::Dependency
|
196
70
|
name: nokogiri
|
197
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -233,26 +107,24 @@ files:
|
|
233
107
|
- indieweb-endpoints.gemspec
|
234
108
|
- lib/indieweb/endpoints.rb
|
235
109
|
- lib/indieweb/endpoints/client.rb
|
236
|
-
- lib/indieweb/endpoints/concerns/registerable.rb
|
237
110
|
- lib/indieweb/endpoints/exceptions.rb
|
238
111
|
- lib/indieweb/endpoints/parsers.rb
|
239
112
|
- lib/indieweb/endpoints/parsers/authorization_endpoint_parser.rb
|
113
|
+
- lib/indieweb/endpoints/parsers/base_parser.rb
|
240
114
|
- lib/indieweb/endpoints/parsers/micropub_parser.rb
|
241
115
|
- lib/indieweb/endpoints/parsers/microsub_parser.rb
|
242
116
|
- lib/indieweb/endpoints/parsers/redirect_uri_parser.rb
|
243
117
|
- lib/indieweb/endpoints/parsers/token_endpoint_parser.rb
|
244
118
|
- lib/indieweb/endpoints/parsers/webmention_parser.rb
|
245
|
-
- lib/indieweb/endpoints/services/
|
246
|
-
- lib/indieweb/endpoints/services/response_body_parser_service.rb
|
247
|
-
- lib/indieweb/endpoints/services/response_headers_parser_service.rb
|
119
|
+
- lib/indieweb/endpoints/services/response_parser_service.rb
|
248
120
|
- lib/indieweb/endpoints/version.rb
|
249
121
|
homepage: https://github.com/indieweb/indieweb-endpoints-ruby
|
250
122
|
licenses:
|
251
123
|
- MIT
|
252
124
|
metadata:
|
253
125
|
bug_tracker_uri: https://github.com/indieweb/indieweb-endpoints-ruby/issues
|
254
|
-
changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/
|
255
|
-
post_install_message:
|
126
|
+
changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v5.0.0/CHANGELOG.md
|
127
|
+
post_install_message:
|
256
128
|
rdoc_options: []
|
257
129
|
require_paths:
|
258
130
|
- lib
|
@@ -260,18 +132,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
260
132
|
requirements:
|
261
133
|
- - ">="
|
262
134
|
- !ruby/object:Gem::Version
|
263
|
-
version: '2.
|
135
|
+
version: '2.5'
|
264
136
|
- - "<"
|
265
137
|
- !ruby/object:Gem::Version
|
266
|
-
version: '2.
|
138
|
+
version: '2.8'
|
267
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
268
140
|
requirements:
|
269
141
|
- - ">="
|
270
142
|
- !ruby/object:Gem::Version
|
271
143
|
version: '0'
|
272
144
|
requirements: []
|
273
|
-
rubygems_version: 3.
|
274
|
-
signing_key:
|
145
|
+
rubygems_version: 3.1.2
|
146
|
+
signing_key:
|
275
147
|
specification_version: 4
|
276
148
|
summary: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
|
277
149
|
test_files: []
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module IndieWeb
|
2
|
-
module Endpoints
|
3
|
-
module Services
|
4
|
-
class HttpRequestService
|
5
|
-
# Defaults derived from Webmention specification examples
|
6
|
-
# https://www.w3.org/TR/webmention/#limits-on-get-requests
|
7
|
-
HTTP_CLIENT_OPTS = {
|
8
|
-
follow: {
|
9
|
-
max_hops: 20
|
10
|
-
},
|
11
|
-
headers: {
|
12
|
-
accept: '*/*',
|
13
|
-
user_agent: 'IndieWeb Endpoint Discovery (https://rubygems.org/gems/indieweb-endpoints)'
|
14
|
-
},
|
15
|
-
timeout_options: {
|
16
|
-
connect_timeout: 5,
|
17
|
-
read_timeout: 5
|
18
|
-
}
|
19
|
-
}.freeze
|
20
|
-
|
21
|
-
def initialize
|
22
|
-
@client = HTTP::Client.new(HTTP_CLIENT_OPTS)
|
23
|
-
end
|
24
|
-
|
25
|
-
def get(uri)
|
26
|
-
client.request(:get, uri)
|
27
|
-
rescue HTTP::ConnectionError,
|
28
|
-
HTTP::TimeoutError,
|
29
|
-
HTTP::Redirector::TooManyRedirectsError => exception
|
30
|
-
raise IndieWeb::Endpoints.const_get(exception.class.name.split('::').last), exception
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
attr_accessor :client
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module IndieWeb
|
2
|
-
module Endpoints
|
3
|
-
module Services
|
4
|
-
class ResponseBodyParserService
|
5
|
-
def 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 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
|