indieweb-endpoints 6.0.0 → 7.1.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: d751a18dc854951b0c3b71429959f2fdd0690ee9ba51a1b5cf6b6cc5dcec5143
4
- data.tar.gz: 5b3dd9ab89de1bf668471c58d4bf8097633125e37b9ccf80d0c94554ae3dbe38
3
+ metadata.gz: d00bf075ce905d49768b047c4963ccc8fb260e3ce7c06a1305a10099bdf6e4a0
4
+ data.tar.gz: 2c50a4fe3f85d401ccf981e5ef4c374e35f2788a2a00422f52df08c7a7c9821f
5
5
  SHA512:
6
- metadata.gz: 8b2dc2195a547c955545ff89d540e40dde34de784490271c6726afd49249f4ebd66bafcdd43bcc3dff30ca9444f306aa4264da7849b19f9401575dbe3dcd49f4
7
- data.tar.gz: 356ab5dbb4ea2b233ab490323bd80da4e61568654a0c1c209fd6e7932fe7af5ba15792ee209f79ab650f54478e18a9d67357b8204c7dc40a4d2cddf2d04dba8f
6
+ metadata.gz: ed757712cf9c99812ebdf2eb514c37b4a78cf0fd9f86c416611ce64a854706eb0e7b08599be0681438a774b76dbc9e03b2bb8434107fd17dec37403686743182
7
+ data.tar.gz: cadd7fad871a5d33f88e9365f7b8b1300c331cd96f2716d17f24ae8eac9eec79c463f4e45c68cb18fa35d602393fd771d3face3723c0acc1e3ab46acba02f7c7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.1.0 / 2022-03-08
4
+
5
+ - Refactor gem code (eba8115)
6
+ - Refactor specs (5b92119)
7
+ - Rescue from `OpenSSL::SSL::SSLError` (4ea38e5)
8
+
9
+ ## 7.0.0 / 2022-01-06
10
+
11
+ - Update runtime dependency versions (5c9430f)
12
+ - **Breaking change:** Update development Ruby version to 2.6.9 and minimum Ruby version to 2.6 (ed17ab1 and 7e4a621)
13
+ - Migrate to GitHub Actions from Travis CI (c019756)
14
+ - Add `rubygems_mfa_required` to gemspec metadata (1f0a40f)
15
+
16
+ ## 6.1.0 / 2021-05-25
17
+
18
+ - Add support for Ruby 3.0 (3394252)
19
+
3
20
  ## 6.0.0 / 2021-05-25
4
21
 
5
22
  - Refactor parsers (e22e0af)
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.5.9 and is additionally tested against Ruby 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.6.9 and is additionally tested against Ruby 2.7, 3.0, and 3.1 using [GitHub Actions](https://github.com/indieweb/indieweb-endpoints-ruby/actions).
12
12
 
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:
13
+ Before making changes to indieweb-endpoints-ruby, you'll want to install Ruby 2.6.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.6.9 using your method of choice, install the project's gems by running:
14
14
 
15
15
  ```sh
16
16
  bundle install
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Gem](https://img.shields.io/gem/v/indieweb-endpoints.svg?logo=rubygems&style=for-the-badge)](https://rubygems.org/gems/indieweb-endpoints)
6
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)
7
+ [![Build](https://img.shields.io/github/workflow/status/indieweb/indieweb-endpoints-ruby/CI?logo=github&style=for-the-badge)](https://github.com/indieweb/indieweb-endpoints-ruby/actions/workflows/ci.yml)
8
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
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
 
@@ -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.5 and newer.
15
+ - Supports Ruby 2.6 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.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).
19
+ Before installing and using indieweb-endpoints-ruby, you'll want to have [Ruby](https://www.ruby-lang.org) 2.6 (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.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).
21
+ indieweb-endpoints-ruby is developed using Ruby 2.6.9 and is additionally tested against Ruby 2.7, 3.0, and 3.1 using [GitHub Actions](https://github.com/indieweb/indieweb-endpoints-ruby/actions).
22
22
 
23
23
  ## Installation
24
24
 
@@ -59,7 +59,7 @@ Should the need arise, you may work with the `IndieWeb::Endpoints::Client` class
59
59
  require 'indieweb/endpoints'
60
60
 
61
61
  client = IndieWeb::Endpoints::Client.new('https://aaronparecki.com')
62
- #=> #<IndieWeb::Endpoints::Client url: "https://aaronparecki.com">
62
+ #=> #<IndieWeb::Endpoints::Client uri: "https://aaronparecki.com">
63
63
 
64
64
  client.response
65
65
  #=> #<HTTP::Response/1.1 200 OK {…}>
@@ -80,6 +80,10 @@ From [httprb/http](https://github.com/httprb/http):
80
80
 
81
81
  - `IndieWeb::Endpoints::HttpError`
82
82
 
83
+ From the Ruby Standard Library's [`OpenSSL::SSL::SSLError`](https://ruby-doc.org/stdlib-2.6.9/libdoc/openssl/rdoc/OpenSSL/SSL/SSLError.html):
84
+
85
+ - `IndieWeb::Endpoints::SSLError`
86
+
83
87
  ## Contributing
84
88
 
85
89
  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.
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/indieweb/endpoints/version'
2
4
 
3
5
  Gem::Specification.new do |spec|
4
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5', '< 2.8')
6
+ spec.required_ruby_version = '>= 2.6', '< 4'
5
7
 
6
8
  spec.name = 'indieweb-endpoints'
7
9
  spec.version = IndieWeb::Endpoints::VERSION
@@ -19,11 +21,13 @@ Gem::Specification.new do |spec|
19
21
 
20
22
  spec.require_paths = ['lib']
21
23
 
22
- spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
23
- spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
24
+ spec.metadata = {
25
+ 'bug_tracker_uri' => "#{spec.homepage}/issues",
26
+ 'changelog_uri' => "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md",
27
+ 'rubygems_mfa_required' => 'true'
28
+ }
24
29
 
25
- spec.add_runtime_dependency 'addressable', '~> 2.7'
26
30
  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'
31
+ spec.add_runtime_dependency 'link-header-parser', '~> 4.0'
32
+ spec.add_runtime_dependency 'nokogiri', '~> 1.13'
29
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module IndieWeb
2
4
  module Endpoints
3
5
  class Client
@@ -10,39 +12,45 @@ module IndieWeb
10
12
  #
11
13
  # client = IndieWeb::Endpoints::Client.new('https://aaronparecki.com')
12
14
  #
13
- # @param url [String] an absolute URL
15
+ # @param url [String, HTTP::URI, #to_s] an absolute URL
16
+ # @raise [IndieWeb::Endpoints::InvalidURIError]
14
17
  def initialize(url)
15
- @url = url.to_str
18
+ @uri = HTTP::URI.parse(url.to_s)
19
+ rescue Addressable::URI::InvalidURIError => e
20
+ raise InvalidURIError, e
16
21
  end
17
22
 
18
23
  # @return [String]
19
24
  def inspect
20
- format(%(#<#{self.class.name}:%#0x url: #{url.inspect}>), object_id)
25
+ %(#<#{self.class.name}:#{format('%#0x', object_id)} uri: "#{uri}">)
21
26
  end
22
27
 
28
+ # A Hash of the discovered IndieWeb endpoints from the provided URL
29
+ #
23
30
  # @return [Hash{Symbol => String, Array, nil}]
24
31
  def endpoints
25
- @endpoints ||= Parsers.registered.transform_values { |parser| parser.new(response).results }
32
+ @endpoints ||= Parser.new(response).results
26
33
  end
27
34
 
28
- # @see https://www.w3.org/TR/webmention/#limits-on-get-requests
35
+ # The HTTP::Response object returned by the provided URL
29
36
  #
30
37
  # @return [HTTP::Response]
38
+ # @raise [IndieWeb::Endpoints::HttpError]
31
39
  def response
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
40
+ @response ||= HTTP.follow(max_hops: 20)
41
+ .headers(HTTP_HEADERS_OPTS)
42
+ .timeout(connect: 5, read: 5)
43
+ .get(uri)
44
+ rescue HTTP::Error => e
45
+ raise HttpError, e
46
+ rescue OpenSSL::SSL::SSLError => e
47
+ raise SSLError, e
35
48
  end
36
49
 
37
50
  private
38
51
 
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
52
+ # @return [HTTP::URI]
53
+ attr_reader :uri
46
54
  end
47
55
  end
48
56
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IndieWeb
4
+ module Endpoints
5
+ # @api private
6
+ class Parser
7
+ # @param response [HTTP::Response]
8
+ def initialize(response)
9
+ @response = response
10
+ end
11
+
12
+ # @return [Hash{Symbol => String, Array<String>, nil}]
13
+ def results
14
+ {
15
+ authorization_endpoint: result_for(:authorization_endpoint),
16
+ micropub: result_for(:micropub),
17
+ microsub: result_for(:microsub),
18
+ redirect_uri: results_for(:redirect_uri),
19
+ token_endpoint: result_for(:token_endpoint),
20
+ webmention: result_for(:webmention, %w[link a])
21
+ }
22
+ end
23
+
24
+ private
25
+
26
+ # @return [HTTP::Response]
27
+ attr_reader :response
28
+
29
+ # @return [IndieWeb::Endpoints::ResponseBodyParser]
30
+ def response_body_parser
31
+ @response_body_parser ||= ResponseBodyParser.new(response)
32
+ end
33
+
34
+ # @return [IndieWeb::Endpoints::ResponseHeadersParser]
35
+ def response_headers_parser
36
+ @response_headers_parser ||= ResponseHeadersParser.new(response)
37
+ end
38
+
39
+ # @param identifier [Symbol]
40
+ # @param nodes [Array<String>]
41
+ # @return [String, nil]
42
+ def result_for(identifier, nodes = ['link'])
43
+ results_for(identifier, nodes)&.first
44
+ end
45
+
46
+ # @param identifier [Symbol]
47
+ # @param nodes [Array<String>]
48
+ # @return [Array<String>, nil]
49
+ # @raise [IndieWeb::Endpoints::InvalidURIError]
50
+ def results_for(identifier, nodes = ['link'])
51
+ results_from_request = [
52
+ response_headers_parser.results_for(identifier),
53
+ response_body_parser.results_for(identifier, nodes)
54
+ ].flatten.compact
55
+
56
+ return if results_from_request.none?
57
+
58
+ results_from_request.map { |endpoint| response.uri.join(endpoint).to_s }.uniq.sort
59
+ rescue Addressable::URI::InvalidURIError => e
60
+ raise InvalidURIError, e
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IndieWeb
4
+ module Endpoints
5
+ # @api private
6
+ class ResponseBodyParser
7
+ # @param response [HTTP::Response]
8
+ def initialize(response)
9
+ @body = response.body.to_s
10
+ @mime_type = response.mime_type
11
+ @uri = response.uri
12
+ end
13
+
14
+ # @param identifier [Symbol]
15
+ # @param nodes [Array<String>]
16
+ # @return [Array<string>, nil]
17
+ def results_for(identifier, nodes = ['link'])
18
+ return unless mime_type == 'text/html'
19
+
20
+ # Reject endpoints that contain a fragment identifier
21
+ selectors = nodes.map { |node| %(#{node}[rel~="#{identifier}"][href]:not([href*="#"])) }.join(',')
22
+
23
+ parsed_body.css(selectors).map { |element| element['href'] }
24
+ end
25
+
26
+ private
27
+
28
+ # @return [String]
29
+ attr_reader :body
30
+
31
+ # @return [String]
32
+ attr_reader :mime_type
33
+
34
+ # @return [HTTP::URI]
35
+ attr_reader :uri
36
+
37
+ # @return [Nokogiri::HTML5::Document]
38
+ def parsed_body
39
+ @parsed_body ||= Nokogiri::HTML5(body)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IndieWeb
4
+ module Endpoints
5
+ # @api private
6
+ class ResponseHeadersParser
7
+ # @param response [HTTP::Response]
8
+ def initialize(response)
9
+ @headers = response.headers.get('link')
10
+ @uri = response.uri
11
+ end
12
+
13
+ # @param headers [Symbol]
14
+ # @return [Array<String>, nil]
15
+ def results_for(identifier)
16
+ return unless parsed_headers.key?(identifier)
17
+
18
+ # Reject endpoints that contain a fragment identifier
19
+ parsed_headers[identifier].reject { |header| HTTP::URI.parse(header.target_uri).fragment }.map(&:target_uri)
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Array<String>]
25
+ attr_reader :headers
26
+
27
+ # @return [HTTP::URI]
28
+ attr_reader :uri
29
+
30
+ # @return [Hash{Symbol => Array<LinkHeaderParser::LinkHeader>}]
31
+ def parsed_headers
32
+ @parsed_headers ||= LinkHeaderParser.parse(headers, base: uri).group_by_relation_type
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module IndieWeb
2
4
  module Endpoints
3
- VERSION = '6.0.0'.freeze
5
+ VERSION = '7.1.0'
4
6
  end
5
7
  end
@@ -1,26 +1,23 @@
1
- require 'addressable/uri'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'http'
3
4
  require 'link-header-parser'
4
5
  require 'nokogiri'
5
6
 
6
- require 'indieweb/endpoints/version'
7
- require 'indieweb/endpoints/exceptions'
8
-
9
- require 'indieweb/endpoints/services/response_parser_service'
7
+ require_relative 'endpoints/version'
10
8
 
11
- require 'indieweb/endpoints/client'
12
- require 'indieweb/endpoints/parsers'
13
-
14
- require 'indieweb/endpoints/parsers/base_parser'
15
- require 'indieweb/endpoints/parsers/authorization_endpoint_parser'
16
- require 'indieweb/endpoints/parsers/micropub_parser'
17
- require 'indieweb/endpoints/parsers/microsub_parser'
18
- require 'indieweb/endpoints/parsers/redirect_uri_parser'
19
- require 'indieweb/endpoints/parsers/token_endpoint_parser'
20
- require 'indieweb/endpoints/parsers/webmention_parser'
9
+ require_relative 'endpoints/client'
10
+ require_relative 'endpoints/parser'
11
+ require_relative 'endpoints/response_body_parser'
12
+ require_relative 'endpoints/response_headers_parser'
21
13
 
22
14
  module IndieWeb
23
15
  module Endpoints
16
+ class Error < StandardError; end
17
+ class HttpError < Error; end
18
+ class InvalidURIError < Error; end
19
+ class SSLError < Error; end
20
+
24
21
  # Discover a URL's IndieAuth, Micropub, Microsub, and Webmention endpoints
25
22
  #
26
23
  # IndieWeb::Endpoints.get('https://aaronparecki.com')
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indieweb-endpoints
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 7.1.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: 2021-05-26 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: addressable
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.7'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.7'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: http
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -44,28 +30,28 @@ dependencies:
44
30
  requirements:
45
31
  - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: '3.0'
33
+ version: '4.0'
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: '3.0'
40
+ version: '4.0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: nokogiri
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '1.11'
47
+ version: '1.13'
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '1.11'
54
+ version: '1.13'
69
55
  description: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
70
56
  email:
71
57
  - jason@sixtwothree.org
@@ -81,24 +67,18 @@ files:
81
67
  - indieweb-endpoints.gemspec
82
68
  - lib/indieweb/endpoints.rb
83
69
  - lib/indieweb/endpoints/client.rb
84
- - lib/indieweb/endpoints/exceptions.rb
85
- - lib/indieweb/endpoints/parsers.rb
86
- - lib/indieweb/endpoints/parsers/authorization_endpoint_parser.rb
87
- - lib/indieweb/endpoints/parsers/base_parser.rb
88
- - lib/indieweb/endpoints/parsers/micropub_parser.rb
89
- - lib/indieweb/endpoints/parsers/microsub_parser.rb
90
- - lib/indieweb/endpoints/parsers/redirect_uri_parser.rb
91
- - lib/indieweb/endpoints/parsers/token_endpoint_parser.rb
92
- - lib/indieweb/endpoints/parsers/webmention_parser.rb
93
- - lib/indieweb/endpoints/services/response_parser_service.rb
70
+ - lib/indieweb/endpoints/parser.rb
71
+ - lib/indieweb/endpoints/response_body_parser.rb
72
+ - lib/indieweb/endpoints/response_headers_parser.rb
94
73
  - lib/indieweb/endpoints/version.rb
95
74
  homepage: https://github.com/indieweb/indieweb-endpoints-ruby
96
75
  licenses:
97
76
  - MIT
98
77
  metadata:
99
78
  bug_tracker_uri: https://github.com/indieweb/indieweb-endpoints-ruby/issues
100
- changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v6.0.0/CHANGELOG.md
101
- post_install_message:
79
+ changelog_uri: https://github.com/indieweb/indieweb-endpoints-ruby/blob/v7.1.0/CHANGELOG.md
80
+ rubygems_mfa_required: 'true'
81
+ post_install_message:
102
82
  rdoc_options: []
103
83
  require_paths:
104
84
  - lib
@@ -106,18 +86,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
86
  requirements:
107
87
  - - ">="
108
88
  - !ruby/object:Gem::Version
109
- version: '2.5'
89
+ version: '2.6'
110
90
  - - "<"
111
91
  - !ruby/object:Gem::Version
112
- version: '2.8'
92
+ version: '4'
113
93
  required_rubygems_version: !ruby/object:Gem::Requirement
114
94
  requirements:
115
95
  - - ">="
116
96
  - !ruby/object:Gem::Version
117
97
  version: '0'
118
98
  requirements: []
119
- rubygems_version: 3.2.16
120
- signing_key:
99
+ rubygems_version: 3.2.33
100
+ signing_key:
121
101
  specification_version: 4
122
102
  summary: Discover a URL’s IndieAuth, Micropub, Microsub, and Webmention endpoints.
123
103
  test_files: []
@@ -1,11 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- class Error < StandardError; end
4
-
5
- class ArgumentError < Error; end
6
-
7
- class HttpError < Error; end
8
-
9
- class InvalidURIError < Error; end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class AuthorizationEndpointParser < BaseParser
5
- @identifier = :authorization_endpoint
6
-
7
- Parsers.register(self)
8
- end
9
- end
10
- end
11
- end
@@ -1,57 +0,0 @@
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
@@ -1,11 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class MicropubParser < BaseParser
5
- @identifier = :micropub
6
-
7
- Parsers.register(self)
8
- end
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class MicrosubParser < BaseParser
5
- @identifier = :microsub
6
-
7
- Parsers.register(self)
8
- end
9
- end
10
- end
11
- end
@@ -1,18 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class RedirectUriParser < BaseParser
5
- @identifier = :redirect_uri
6
-
7
- Parsers.register(self)
8
-
9
- # @return [Array<String>, nil]
10
- def results
11
- return if mapped_results.none?
12
-
13
- mapped_results
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class TokenEndpointParser < BaseParser
5
- @identifier = :token_endpoint
6
-
7
- Parsers.register(self)
8
- end
9
- end
10
- end
11
- end
@@ -1,22 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- class WebmentionParser < BaseParser
5
- @identifier = :webmention
6
-
7
- Parsers.register(self)
8
-
9
- private
10
-
11
- def results_for_node(node)
12
- Services::ResponseParserService.parse_body(parsed_response_body, self.class.identifier, node)
13
- end
14
-
15
- # https://www.w3.org/TR/webmention/#sender-discovers-receiver-webmention-endpoint
16
- def results_from_body
17
- @results_from_body ||= [results_for_node('link'), results_for_node('a')].flatten.compact
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,13 +0,0 @@
1
- module IndieWeb
2
- module Endpoints
3
- module Parsers
4
- def self.register(klass)
5
- registered[klass.identifier] = klass
6
- end
7
-
8
- def self.registered
9
- @registered ||= {}
10
- end
11
- end
12
- end
13
- end
@@ -1,25 +0,0 @@
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