indieweb-endpoints 1.1.0 → 6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08489907fd615d0e6eec6e6c80aee184713c5a65014c150255517413688693dd'
4
- data.tar.gz: 0d426b9e30cc91dacec91f26fea509d0b761ac30b96c02336d28b99d0aad68d9
3
+ metadata.gz: d751a18dc854951b0c3b71429959f2fdd0690ee9ba51a1b5cf6b6cc5dcec5143
4
+ data.tar.gz: 5b3dd9ab89de1bf668471c58d4bf8097633125e37b9ccf80d0c94554ae3dbe38
5
5
  SHA512:
6
- metadata.gz: 468db55b447dddc64b56c60a013111d74f7d25c9f71ae3ca728484bc60a283652f87cefe92ec187125f57bce1a7512bcb02047c0e85bac671297bcfce95d5e0a
7
- data.tar.gz: bd0d10b05873cefe89c64ae2144896c59c06556e58d8980da19dd1a85f5959a9c1601f2c15c2689faba6b86a115edfb4419d8ec2d9ce5ff4b1fac83e40f6a209
6
+ metadata.gz: 8b2dc2195a547c955545ff89d540e40dde34de784490271c6726afd49249f4ebd66bafcdd43bcc3dff30ca9444f306aa4264da7849b19f9401575dbe3dcd49f4
7
+ data.tar.gz: 356ab5dbb4ea2b233ab490323bd80da4e61568654a0c1c209fd6e7932fe7af5ba15792ee209f79ab650f54478e18a9d67357b8204c7dc40a4d2cddf2d04dba8f
data/CHANGELOG.md CHANGED
@@ -1,8 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.0.0 / 2021-05-25
4
+
5
+ - Refactor parsers (e22e0af)
6
+ - Simplify exception handling (65361ee)
7
+ - Update http dependency to 5.0 (44f2d23)
8
+ - **Breaking change:** Favor Addressable::URI.join over Absolutely (0bc5049)
9
+ - Update development Ruby version to 2.5.9 (3439cce)
10
+
11
+ ## 5.0.0 / 2020-11-11
12
+
13
+ - Update absolutely and link-header-parser dependencies (064696e)
14
+
15
+ ## 4.0.0 / 2020-07-21
16
+
17
+ - **Breaking change:** Return a Hash of endpoints instead of an OpenStruct (15dc387)
18
+ - Update [link-header-parser](https://rubygems.org/gems/link-header-parser) dependency to v2.0.0 (2255e6b)
19
+ - **Breaking change:** Update development Ruby version to 2.5.8 and minimum Ruby version to 2.5 (dd5a142)
20
+ - Refactor response headers/body parsers into a single class (ee02da3)
21
+ - Refactor `IndieWeb::Endpoints::Client` and remove `HttpRequestService` (2732616)
22
+ - Add offending url to exception message (#5) (4bf7a54)
23
+
24
+ ## 3.0.0 / 2020-05-14
25
+
26
+ - Update Absolutely and LinkHeaderParser dependencies (9e0a64a)
27
+ - Move development dependencies to `Gemfile` (67067f3)
28
+ - Update development Ruby version to 2.4.10 (f5430f9)
29
+
30
+ ## 2.0.0 / 2020-01-25
31
+
32
+ - Downgrade HTTP gem version constraint to ~> 4.3 (cb63230)
33
+
3
34
  ## 1.1.0 / 2020-01-20
4
35
 
5
36
  - Expand supported Ruby versions to include 2.7 (ae63ed0)
37
+ - Update project Ruby version to 2.4.9 (e576ad6)
6
38
 
7
39
  ## 1.0.2 / 2019-08-31
8
40
 
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.4.9 and is additionally tested against Ruby 2.5, 2.6, and 2.7 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
11
+ indieweb-endpoints-ruby is developed using Ruby 2.5.9 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.4.9. 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.9 using your method of choice, install the project's gems by running:
13
+ Before making changes to indieweb-endpoints-ruby, you'll want to install Ruby 2.5.9. 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.9 using your method of choice, install the project's gems by running:
14
14
 
15
15
  ```sh
16
16
  bundle install
@@ -22,7 +22,7 @@ bundle install
22
22
  1. Install development dependencies as outlined above.
23
23
  1. Create a feature branch for the code changes you're looking to make: `git checkout -b my-new-feature`.
24
24
  1. _Write some code!_
25
- 1. If your changes would benefit from testing, add the necessary tests and verify everything passes by running `bundle exec rspec`.
25
+ 1. If your changes would benefit from testing, add the necessary tests and verify everything passes by running `bin/ci`.
26
26
  1. Commit your changes: `git commit -am 'Add some new feature or fix some issue'`. _(See [this excellent article](https://chris.beams.io/posts/git-commit/) for tips on writing useful Git commit messages.)_
27
27
  1. Push the branch to your fork: `git push -u origin my-new-feature`.
28
28
  1. Create a new [pull request][pulls] and we'll review your changes.
data/README.md CHANGED
@@ -2,23 +2,23 @@
2
2
 
3
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
- [![Gem](https://img.shields.io/gem/v/indieweb-endpoints.svg?style=for-the-badge)](https://rubygems.org/gems/indieweb-endpoints)
6
- [![Downloads](https://img.shields.io/gem/dt/indieweb-endpoints.svg?style=for-the-badge)](https://rubygems.org/gems/indieweb-endpoints)
7
- [![Build](https://img.shields.io/travis/com/indieweb/indieweb-endpoints-ruby/master.svg?style=for-the-badge)](https://travis-ci.com/indieweb/indieweb-endpoints-ruby)
8
- [![Maintainability](https://img.shields.io/codeclimate/maintainability/indieweb/indieweb-endpoints-ruby.svg?style=for-the-badge)](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby)
9
- [![Coverage](https://img.shields.io/codeclimate/c/indieweb/indieweb-endpoints-ruby.svg?style=for-the-badge)](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby/code)
5
+ [![Gem](https://img.shields.io/gem/v/indieweb-endpoints.svg?logo=rubygems&style=for-the-badge)](https://rubygems.org/gems/indieweb-endpoints)
6
+ [![Downloads](https://img.shields.io/gem/dt/indieweb-endpoints.svg?logo=rubygems&style=for-the-badge)](https://rubygems.org/gems/indieweb-endpoints)
7
+ [![Build](https://img.shields.io/travis/com/indieweb/indieweb-endpoints-ruby/main.svg?logo=travis&style=for-the-badge)](https://travis-ci.com/indieweb/indieweb-endpoints-ruby)
8
+ [![Maintainability](https://img.shields.io/codeclimate/maintainability/indieweb/indieweb-endpoints-ruby.svg?logo=code-climate&style=for-the-badge)](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby)
9
+ [![Coverage](https://img.shields.io/codeclimate/c/indieweb/indieweb-endpoints-ruby.svg?logo=code-climate&style=for-the-badge)](https://codeclimate.com/github/indieweb/indieweb-endpoints-ruby/code)
10
10
 
11
11
  ## Key Features
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.4 and newer.
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.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).
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.4.9 and is additionally tested against Ruby 2.5, 2.6, and 2.7 using [Travis CI](https://travis-ci.com/indieweb/indieweb-endpoints-ruby).
21
+ indieweb-endpoints-ruby is developed using Ruby 2.5.9 and is additionally tested against Ruby 2.6, 2.7, and 3.0 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
- endpoints = IndieWeb::Endpoints.get('https://aaronparecki.com')
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
- Each attribute will return either a `String` representing a URL or `nil`. The `redirect_uri` attribute will return either an `Array` or `nil` since a given URL may register multiple callback URLs.
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,36 +59,30 @@ 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
- puts client.response # => #<HTTP::Response/1.1 200 OK {…}>
78
-
79
- endpoints = client.endpoints
64
+ client.response
65
+ #=> #<HTTP::Response/1.1 200 OK {…}>
80
66
 
81
- puts endpoints.authorization_endpoint # => 'https://aaronparecki.com/auth'
82
- puts endpoints.micropub # => 'https://aaronparecki.com/micropub'
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
90
72
 
91
- 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`).
73
+ There are several exceptions that may be raised by indieweb-endpoints-ruby's underlying dependencies. These errors are raised as subclasses of `IndieWeb::Endpoints::Error` (which itself is a subclass of `StandardError`).
92
74
 
93
- From [jgarber623/absolutely](https://github.com/jgarber623/absolutely) and [sporkmonger/addressable](https://github.com/sporkmonger/addressable):
75
+ From [sporkmonger/addressable](https://github.com/sporkmonger/addressable):
94
76
 
95
77
  - `IndieWeb::Endpoints::InvalidURIError`
96
78
 
97
79
  From [httprb/http](https://github.com/httprb/http):
98
80
 
99
- - `IndieWeb::Endpoints::ConnectionError`
100
- - `IndieWeb::Endpoints::TimeoutError`
101
- - `IndieWeb::Endpoints::TooManyRedirectsError`
81
+ - `IndieWeb::Endpoints::HttpError`
102
82
 
103
83
  ## Contributing
104
84
 
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/master/CONTRIBUTING.md) for details.
85
+ 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
86
 
107
87
  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
88
 
@@ -1,10 +1,7 @@
1
- lib = File.expand_path('lib', __dir__)
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 = ['>= 2.4', '< 2.8']
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,17 @@ 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 = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(bin|spec)/}) }
16
+ spec.files = Dir['lib/**/*'].reject { |f| File.directory?(f) }
17
+ spec.files += %w[LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md]
18
+ spec.files += %w[indieweb-endpoints.gemspec]
20
19
 
21
20
  spec.require_paths = ['lib']
22
21
 
23
- spec.metadata = {
24
- 'bug_tracker_uri' => "#{spec.homepage}/issues",
25
- 'changelog_uri' => "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
26
- }
27
-
28
- spec.add_development_dependency 'rake', '~> 13.0'
29
- spec.add_development_dependency 'reek', '~> 5.6'
30
- spec.add_development_dependency 'rspec', '~> 3.9'
31
- spec.add_development_dependency 'rubocop', '~> 0.79.0'
32
- spec.add_development_dependency 'rubocop-performance', '~> 1.5'
33
- spec.add_development_dependency 'rubocop-rspec', '~> 1.37'
34
- spec.add_development_dependency 'simplecov', '~> 0.17.1'
35
- spec.add_development_dependency 'simplecov-console', '~> 0.6.0'
36
- spec.add_development_dependency 'webmock', '~> 3.8'
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', '~> 3.1'
39
25
  spec.add_runtime_dependency 'addressable', '~> 2.7'
40
- spec.add_runtime_dependency 'http', '~> 5.0.0.pre'
41
- spec.add_runtime_dependency 'link-header-parser', '~> 0.3.0'
42
- spec.add_runtime_dependency 'nokogiri', '~> 1.10'
26
+ spec.add_runtime_dependency 'http', '~> 5.0'
27
+ spec.add_runtime_dependency 'link-header-parser', '~> 3.0'
28
+ spec.add_runtime_dependency 'nokogiri', '~> 1.11'
43
29
  end
@@ -1,6 +1,3 @@
1
- require 'ostruct'
2
-
3
- require 'absolutely'
4
1
  require 'addressable/uri'
5
2
  require 'http'
6
3
  require 'link-header-parser'
@@ -9,15 +6,12 @@ require 'nokogiri'
9
6
  require 'indieweb/endpoints/version'
10
7
  require 'indieweb/endpoints/exceptions'
11
8
 
12
- require 'indieweb/endpoints/concerns/registerable'
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'
9
+ require 'indieweb/endpoints/services/response_parser_service'
17
10
 
18
11
  require 'indieweb/endpoints/client'
19
12
  require 'indieweb/endpoints/parsers'
20
13
 
14
+ require 'indieweb/endpoints/parsers/base_parser'
21
15
  require 'indieweb/endpoints/parsers/authorization_endpoint_parser'
22
16
  require 'indieweb/endpoints/parsers/micropub_parser'
23
17
  require 'indieweb/endpoints/parsers/microsub_parser'
@@ -27,6 +21,12 @@ require 'indieweb/endpoints/parsers/webmention_parser'
27
21
 
28
22
  module IndieWeb
29
23
  module Endpoints
24
+ # Discover a URL's IndieAuth, Micropub, Microsub, and Webmention endpoints
25
+ #
26
+ # IndieWeb::Endpoints.get('https://aaronparecki.com')
27
+ #
28
+ # @param url [String] an absolute URL
29
+ # @return [Hash{Symbol => String, Array, nil}]
30
30
  def self.get(url)
31
31
  Client.new(url).endpoints
32
32
  end
@@ -1,27 +1,48 @@
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
- @uri = Addressable::URI.parse(url)
15
+ @url = url.to_str
16
+ end
6
17
 
7
- raise ArgumentError, 'url must be an absolute URL (e.g. https://example.com)' unless @uri.absolute? && @uri.scheme.match?(/^https?$/)
8
- rescue Addressable::URI::InvalidURIError => exception
9
- raise InvalidURIError, exception
10
- rescue NoMethodError, TypeError
11
- raise ArgumentError, "url must be a String (given #{url.class})"
18
+ # @return [String]
19
+ def inspect
20
+ format(%(#<#{self.class.name}:%#0x url: #{url.inspect}>), object_id)
12
21
  end
13
22
 
23
+ # @return [Hash{Symbol => String, Array, nil}]
14
24
  def endpoints
15
- @endpoints ||= OpenStruct.new(Parsers.registered.transform_values { |parser| parser.new(response).results })
25
+ @endpoints ||= Parsers.registered.transform_values { |parser| parser.new(response).results }
16
26
  end
17
27
 
28
+ # @see https://www.w3.org/TR/webmention/#limits-on-get-requests
29
+ #
30
+ # @return [HTTP::Response]
18
31
  def response
19
- @response ||= Services::HttpRequestService.new.get(uri)
32
+ @response ||= HTTP.follow(max_hops: 20).headers(HTTP_HEADERS_OPTS).timeout(connect: 5, read: 5).get(uri)
33
+ rescue HTTP::Error => exception
34
+ raise HttpError, exception
20
35
  end
21
36
 
22
37
  private
23
38
 
24
- attr_accessor :uri
39
+ attr_accessor :url
40
+
41
+ def uri
42
+ @uri ||= Addressable::URI.parse(url)
43
+ rescue Addressable::URI::InvalidURIError => exception
44
+ raise InvalidURIError, exception
45
+ end
25
46
  end
26
47
  end
27
48
  end
@@ -1,15 +1,11 @@
1
1
  module IndieWeb
2
2
  module Endpoints
3
- class IndieWebEndpointsError < StandardError; end
3
+ class Error < StandardError; end
4
4
 
5
- class ArgumentError < IndieWebEndpointsError; end
5
+ class ArgumentError < Error; end
6
6
 
7
- class ConnectionError < IndieWebEndpointsError; end
7
+ class HttpError < Error; end
8
8
 
9
- class InvalidURIError < IndieWebEndpointsError; end
10
-
11
- class TimeoutError < IndieWebEndpointsError; end
12
-
13
- class TooManyRedirectsError < IndieWebEndpointsError; end
9
+ class InvalidURIError < Error; end
14
10
  end
15
11
  end
@@ -1,40 +1,12 @@
1
1
  module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
- extend Concerns::Registerable
5
-
6
- class BaseParser
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
- def results_from_http_request
36
- @results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
37
- end
8
+ def self.registered
9
+ @registered ||= {}
38
10
  end
39
11
  end
40
12
  end
@@ -2,9 +2,7 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class AuthorizationEndpointParser < BaseParser
5
- def self.identifier
6
- :authorization_endpoint
7
- end
5
+ @identifier = :authorization_endpoint
8
6
 
9
7
  Parsers.register(self)
10
8
  end
@@ -0,0 +1,57 @@
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| Addressable::URI.join(response.uri, endpoint).to_s }.uniq.sort
27
+ rescue Addressable::URI::InvalidURIError => exception
28
+ raise InvalidURIError, exception
29
+ end
30
+
31
+ def parsed_response_body
32
+ @parsed_response_body ||= Nokogiri::HTML(response.body.to_s)
33
+ end
34
+
35
+ def parsed_response_headers
36
+ @parsed_response_headers ||= LinkHeaderParser.parse(response.headers.get('link'), base: response.uri)
37
+ end
38
+
39
+ def results_from_body
40
+ return if response.mime_type != 'text/html'
41
+
42
+ Services::ResponseParserService.parse_body(parsed_response_body, self.class.identifier)
43
+ end
44
+
45
+ def results_from_headers
46
+ return if parsed_response_headers.none?
47
+
48
+ Services::ResponseParserService.parse_headers(parsed_response_headers.group_by_relation_type, self.class.identifier)
49
+ end
50
+
51
+ def results_from_http_request
52
+ @results_from_http_request ||= [results_from_headers, results_from_body].flatten.compact
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -2,9 +2,7 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class MicropubParser < BaseParser
5
- def self.identifier
6
- :micropub
7
- end
5
+ @identifier = :micropub
8
6
 
9
7
  Parsers.register(self)
10
8
  end
@@ -2,9 +2,7 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class MicrosubParser < BaseParser
5
- def self.identifier
6
- :microsub
7
- end
5
+ @identifier = :microsub
8
6
 
9
7
  Parsers.register(self)
10
8
  end
@@ -2,14 +2,13 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class RedirectUriParser < BaseParser
5
- def self.identifier
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
- return unless mapped_results.any?
11
+ return if mapped_results.none?
13
12
 
14
13
  mapped_results
15
14
  end
@@ -2,9 +2,7 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class TokenEndpointParser < BaseParser
5
- def self.identifier
6
- :token_endpoint
7
- end
5
+ @identifier = :token_endpoint
8
6
 
9
7
  Parsers.register(self)
10
8
  end
@@ -2,16 +2,14 @@ module IndieWeb
2
2
  module Endpoints
3
3
  module Parsers
4
4
  class WebmentionParser < BaseParser
5
- def self.identifier
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::ResponseBodyParserService.new.parse(response, self.class.identifier, node)
12
+ Services::ResponseParserService.parse_body(parsed_response_body, 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,25 @@
1
+ module IndieWeb
2
+ module Endpoints
3
+ module Services
4
+ class ResponseParserService
5
+ # @param body [Nokogiri::HTML::Document]
6
+ # @param identifier [Symbol]
7
+ # @return [Array<String>]
8
+ def self.parse_body(body, identifier, node = 'link')
9
+ # Reject endpoints that contain a fragment identifier
10
+ body.css(%(#{node}[rel~="#{identifier}"][href]:not([href*="#"]))).map { |element| element['href'] }
11
+ end
12
+
13
+ # @param headers [Hash{Symbol => Array<LinkHeaderParser::LinkHeader}]
14
+ # @param identifier [Symbol]
15
+ # @return [Array<String>, nil]
16
+ def self.parse_headers(headers, identifier)
17
+ return unless headers.key?(identifier)
18
+
19
+ # Reject endpoints that contain a fragment identifier
20
+ headers[identifier].reject { |header| Addressable::URI.parse(header.target_uri).fragment }.map(&:target_uri)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,5 @@
1
1
  module IndieWeb
2
2
  module Endpoints
3
- VERSION = '1.1.0'.freeze
3
+ VERSION = '6.0.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,155 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indieweb-endpoints
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 6.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: 2020-01-20 00:00:00.000000000 Z
11
+ date: 2021-05-26 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: '13.0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '13.0'
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.6'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '5.6'
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.9'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.9'
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.79.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.79.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.5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.5'
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.37'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '1.37'
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.1
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.1
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.6.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.6.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.8'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '3.8'
139
- - !ruby/object:Gem::Dependency
140
- name: absolutely
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '3.1'
146
- type: :runtime
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '3.1'
153
13
  - !ruby/object:Gem::Dependency
154
14
  name: addressable
155
15
  requirement: !ruby/object:Gem::Requirement
@@ -170,42 +30,42 @@ dependencies:
170
30
  requirements:
171
31
  - - "~>"
172
32
  - !ruby/object:Gem::Version
173
- version: 5.0.0.pre
33
+ version: '5.0'
174
34
  type: :runtime
175
35
  prerelease: false
176
36
  version_requirements: !ruby/object:Gem::Requirement
177
37
  requirements:
178
38
  - - "~>"
179
39
  - !ruby/object:Gem::Version
180
- version: 5.0.0.pre
40
+ version: '5.0'
181
41
  - !ruby/object:Gem::Dependency
182
42
  name: link-header-parser
183
43
  requirement: !ruby/object:Gem::Requirement
184
44
  requirements:
185
45
  - - "~>"
186
46
  - !ruby/object:Gem::Version
187
- version: 0.3.0
47
+ version: '3.0'
188
48
  type: :runtime
189
49
  prerelease: false
190
50
  version_requirements: !ruby/object:Gem::Requirement
191
51
  requirements:
192
52
  - - "~>"
193
53
  - !ruby/object:Gem::Version
194
- version: 0.3.0
54
+ version: '3.0'
195
55
  - !ruby/object:Gem::Dependency
196
56
  name: nokogiri
197
57
  requirement: !ruby/object:Gem::Requirement
198
58
  requirements:
199
59
  - - "~>"
200
60
  - !ruby/object:Gem::Version
201
- version: '1.10'
61
+ version: '1.11'
202
62
  type: :runtime
203
63
  prerelease: false
204
64
  version_requirements: !ruby/object:Gem::Requirement
205
65
  requirements:
206
66
  - - "~>"
207
67
  - !ruby/object:Gem::Version
208
- version: '1.10'
68
+ version: '1.11'
209
69
  description: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
210
70
  email:
211
71
  - jason@sixtwothree.org
@@ -213,46 +73,32 @@ executables: []
213
73
  extensions: []
214
74
  extra_rdoc_files: []
215
75
  files:
216
- - ".editorconfig"
217
- - ".github/CODEOWNERS"
218
- - ".gitignore"
219
- - ".reek.yml"
220
- - ".rspec"
221
- - ".rubocop"
222
- - ".rubocop.yml"
223
- - ".ruby-version"
224
- - ".simplecov"
225
- - ".travis.yml"
226
76
  - CHANGELOG.md
227
77
  - CODE_OF_CONDUCT.md
228
78
  - CONTRIBUTING.md
229
- - Gemfile
230
79
  - LICENSE
231
80
  - README.md
232
- - Rakefile
233
81
  - indieweb-endpoints.gemspec
234
82
  - lib/indieweb/endpoints.rb
235
83
  - lib/indieweb/endpoints/client.rb
236
- - lib/indieweb/endpoints/concerns/registerable.rb
237
84
  - lib/indieweb/endpoints/exceptions.rb
238
85
  - lib/indieweb/endpoints/parsers.rb
239
86
  - lib/indieweb/endpoints/parsers/authorization_endpoint_parser.rb
87
+ - lib/indieweb/endpoints/parsers/base_parser.rb
240
88
  - lib/indieweb/endpoints/parsers/micropub_parser.rb
241
89
  - lib/indieweb/endpoints/parsers/microsub_parser.rb
242
90
  - lib/indieweb/endpoints/parsers/redirect_uri_parser.rb
243
91
  - lib/indieweb/endpoints/parsers/token_endpoint_parser.rb
244
92
  - lib/indieweb/endpoints/parsers/webmention_parser.rb
245
- - lib/indieweb/endpoints/services/http_request_service.rb
246
- - lib/indieweb/endpoints/services/response_body_parser_service.rb
247
- - lib/indieweb/endpoints/services/response_headers_parser_service.rb
93
+ - lib/indieweb/endpoints/services/response_parser_service.rb
248
94
  - lib/indieweb/endpoints/version.rb
249
95
  homepage: https://github.com/indieweb/indieweb-endpoints-ruby
250
96
  licenses:
251
97
  - MIT
252
98
  metadata:
253
99
  bug_tracker_uri: https://github.com/indieweb/indieweb-endpoints-ruby/issues
254
- changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v1.1.0/CHANGELOG.md
255
- post_install_message:
100
+ changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v6.0.0/CHANGELOG.md
101
+ post_install_message:
256
102
  rdoc_options: []
257
103
  require_paths:
258
104
  - lib
@@ -260,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
260
106
  requirements:
261
107
  - - ">="
262
108
  - !ruby/object:Gem::Version
263
- version: '2.4'
109
+ version: '2.5'
264
110
  - - "<"
265
111
  - !ruby/object:Gem::Version
266
112
  version: '2.8'
@@ -270,8 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
116
  - !ruby/object:Gem::Version
271
117
  version: '0'
272
118
  requirements: []
273
- rubygems_version: 3.0.6
274
- signing_key:
119
+ rubygems_version: 3.2.16
120
+ signing_key:
275
121
  specification_version: 4
276
122
  summary: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
277
123
  test_files: []
data/.editorconfig DELETED
@@ -1,14 +0,0 @@
1
- # EditorConfig is awesome: https://EditorConfig.org
2
- root = true
3
-
4
- [*]
5
- charset = utf-8
6
- end_of_line = lf
7
- insert_final_newline = true
8
- indent_size = 2
9
- indent_style = space
10
- trim_trailing_whitespace = true
11
-
12
- [*.md]
13
- indent_size = 4
14
- indent_style = tab
data/.github/CODEOWNERS DELETED
@@ -1 +0,0 @@
1
- * jgarber623
data/.gitignore DELETED
@@ -1,34 +0,0 @@
1
- *.gem
2
- *.rbc
3
- /.config
4
- /coverage/
5
- /InstalledFiles
6
- /pkg/
7
- /spec/reports/
8
- /spec/examples.txt
9
- /test/tmp/
10
- /test/version_tmp/
11
- /tmp/
12
-
13
- # Used by dotenv library to load environment variables.
14
- # .env
15
-
16
- # Documentation cache and generated files:
17
- /.yardoc/
18
- /_yardoc/
19
- /doc/
20
- /rdoc/
21
-
22
- # Environment normalization:
23
- /.bundle/
24
- /vendor/bundle
25
- /lib/bundler/man/
26
-
27
- # for a library or gem, you might want to ignore these files since the code is
28
- # intended to run in multiple environments; otherwise, check them in:
29
- Gemfile.lock
30
- # .ruby-version
31
- # .ruby-gemset
32
-
33
- # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
- .rvmrc
data/.reek.yml DELETED
@@ -1,11 +0,0 @@
1
- detectors:
2
- IrresponsibleModule:
3
- enabled: false
4
- UtilityFunction:
5
- exclude:
6
- - FixtureHelpers#read_fixture
7
- - IndieWeb::Endpoints::Services::ResponseBodyParserService#parse
8
- - IndieWeb::Endpoints::Services::ResponseHeadersParserService#parse
9
-
10
- exclude_paths:
11
- - vendor/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --order random
2
- --require spec_helper
data/.rubocop DELETED
@@ -1,3 +0,0 @@
1
- --display-style-guide
2
- --extra-details
3
- --parallel
data/.rubocop.yml DELETED
@@ -1,30 +0,0 @@
1
- require:
2
- - rubocop-performance
3
- - rubocop-rspec
4
-
5
- Layout/HashAlignment:
6
- EnforcedHashRocketStyle: table
7
-
8
- Layout/LineLength:
9
- Enabled: false
10
-
11
- Metrics/BlockLength:
12
- Exclude:
13
- - indieweb-endpoints.gemspec
14
- - spec/**/*.rb
15
-
16
- Naming/RescuedExceptionsVariableName:
17
- PreferredName: exception
18
-
19
- RSpec/FilePath:
20
- Exclude:
21
- - spec/lib/indieweb/**/*_spec.rb
22
-
23
- Style/Documentation:
24
- Enabled: false
25
-
26
- Style/FrozenStringLiteralComment:
27
- Enabled: false
28
-
29
- Style/SymbolArray:
30
- Enabled: false
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.4.9
data/.simplecov DELETED
@@ -1,11 +0,0 @@
1
- require 'simplecov-console'
2
-
3
- formatters = [SimpleCov::Formatter::HTMLFormatter]
4
-
5
- if RSpec.configuration.files_to_run.length > 1
6
- formatters << SimpleCov::Formatter::Console
7
- end
8
-
9
- SimpleCov.start do
10
- formatter SimpleCov::Formatter::MultiFormatter.new(formatters)
11
- end
data/.travis.yml DELETED
@@ -1,16 +0,0 @@
1
- dist: bionic
2
- language: ruby
3
- rvm:
4
- - 2.4
5
- - 2.5
6
- - 2.6
7
- - 2.7
8
- cache: bundler
9
- before_script:
10
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
11
- - chmod +x ./cc-test-reporter
12
- - ./cc-test-reporter before-build
13
- after_script:
14
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
- notifications:
16
- email: false
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in indieweb-endpoints.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,17 +0,0 @@
1
- require 'bundler/gem_tasks'
2
-
3
- require 'reek/rake/task'
4
- require 'rspec/core/rake_task'
5
- require 'rubocop/rake_task'
6
-
7
- Reek::Rake::Task.new do |task|
8
- task.fail_on_error = false
9
- end
10
-
11
- RSpec::Core::RakeTask.new
12
-
13
- RuboCop::RakeTask.new do |task|
14
- task.fail_on_error = false
15
- end
16
-
17
- task default: [:rubocop, :reek, :spec]
@@ -1,15 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Concerns
4
- module Registerable
5
- def register(klass)
6
- registered[klass.identifier] = klass
7
- end
8
-
9
- def registered
10
- @registered ||= {}
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -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