@@ -9,16 +9,43 @@ def initialize(response)
99 @response = response
1010 end
1111
12- # @return [Hash{Symbol => String, Array<String>, nil}]
13- def results
12+ # @param identifier [String]
13+ # @param node_names [Array<String>]
14+ #
15+ # @return [Array<String>]
16+ #
17+ # @raise [InvalidURIError]
18+ def matches ( identifier , node_names : [ "link" ] )
19+ results =
20+ ( matches_from_headers ( identifier ) + matches_from_body ( identifier , node_names ) )
21+ . compact
22+ . map! { |endpoint | response . uri . join ( endpoint ) . to_s }
23+
24+ results . uniq!
25+ results . sort!
26+
27+ results
28+ rescue Addressable ::URI ::InvalidURIError => e
29+ raise InvalidURIError , e
30+ end
31+
32+ # @param (see #matches)
33+ #
34+ # @return [String]
35+ def match ( identifier , **kwargs )
36+ matches ( identifier , **kwargs ) . first
37+ end
38+
39+ # @return [Hash{Symbol => String, Array, nil}]
40+ def to_h
1441 {
15- authorization_endpoint : result_for ( : authorization_endpoint) ,
16- "indieauth-metadata" : result_for ( : "indieauth-metadata") ,
17- micropub : result_for ( : micropub) ,
18- microsub : result_for ( : microsub) ,
19- redirect_uri : results_for ( : redirect_uri) ,
20- token_endpoint : result_for ( : token_endpoint) ,
21- webmention : result_for ( : webmention, [ "link" , "a" ] ) ,
42+ authorization_endpoint : match ( " authorization_endpoint" ) ,
43+ "indieauth-metadata" : match ( "indieauth-metadata" ) ,
44+ micropub : match ( " micropub" ) ,
45+ microsub : match ( " microsub" ) ,
46+ redirect_uri : ( redirect_uri = matches ( "redirect_uri" ) ) . any? ? redirect_uri : nil ,
47+ token_endpoint : match ( " token_endpoint" ) ,
48+ webmention : match ( " webmention" , node_names : [ "link" , "a" ] ) ,
2249 }
2350 end
2451
@@ -27,38 +54,32 @@ def results
2754 # @return [HTTP::Response]
2855 attr_reader :response
2956
30- # @return [IndieWeb::Endpoints::ResponseBodyParser ]
31- def response_body_parser
32- @response_body_parser ||= ResponseBodyParser . new ( response )
57+ # @return [Nokogiri::HTML5::Document ]
58+ def body
59+ @body ||= Nokogiri :: HTML5 ( response . body )
3360 end
3461
35- # @return [IndieWeb::Endpoints::ResponseHeadersParser ]
36- def response_headers_parser
37- @response_headers_parser ||= ResponseHeadersParser . new ( response )
62+ # @return [Hash{Symbol => Array<LinkHeaderParser::LinkHeader>} ]
63+ def headers
64+ @headers ||= LinkHeaderParser . parse ( response . headers . get ( "link" ) , base : response . uri ) . group_by_relation_type
3865 end
3966
40- # @param identifier [Symbol]
41- # @param nodes [Array<String>]
42- # @return [String, nil]
43- def result_for ( identifier , nodes = [ "link" ] )
44- results_for ( identifier , nodes ) &.first
45- end
67+ # @return [Array<String>]
68+ def matches_from_body ( identifier , node_names )
69+ return [ ] unless response . mime_type == "text/html"
4670
47- # @param identifier [Symbol]
48- # @param nodes [Array<String>]
49- # @return [Array<String>, nil]
50- # @raise [IndieWeb::Endpoints::InvalidURIError]
51- def results_for ( identifier , nodes = [ "link" ] )
52- results_from_request = [
53- response_headers_parser . results_for ( identifier ) ,
54- response_body_parser . results_for ( identifier , nodes ) ,
55- ] . flatten . compact
71+ # Reject endpoints that contain a fragment identifier.
72+ selectors = node_names . map { |node | %(#{ node } [rel~="#{ identifier } "][href]:not([href*="#"])) } . join ( "," )
5673
57- return if results_from_request . none?
74+ body . css ( selectors ) . map { |element | element [ "href" ] }
75+ end
5876
59- results_from_request . map { |endpoint | response . uri . join ( endpoint ) . to_s } . uniq . sort
60- rescue Addressable ::URI ::InvalidURIError => e
61- raise InvalidURIError , e
77+ # @return [Array<String>]
78+ def matches_from_headers ( identifier )
79+ # Reject endpoints that contain a fragment identifier.
80+ Array ( headers [ identifier . to_sym ] )
81+ . filter { |header | !HTTP ::URI . parse ( header . target_uri ) . fragment }
82+ . map ( &:target_uri )
6283 end
6384 end
6485 end
0 commit comments