diff options
author | Benjamin Neff <benjamin@coding4coffee.ch> | 2022-07-23 00:46:33 +0300 |
---|---|---|
committer | Benjamin Neff <benjamin@coding4coffee.ch> | 2022-07-23 01:53:07 +0300 |
commit | e984fa7d91a287bc0882cc3db2f451158035243b (patch) | |
tree | eaf0dcd44c0162bb301d34ec2df7d6da61e647e2 | |
parent | 428c97d089a576e9221c6e3b1ebab76adfb3d088 (diff) |
Don't use host-meta in connection tester anymore
This route was removed from the federation and doesn't exist anymore, so
checking for it doesn't make any sense.
But lets check if a server responds to /.well-known/nodeinfo instead.
All other software which supports the diaspora protocol should have this
endpoint by now. Parsing/validating nodeinfo is still handled
gracefully.
closes #8377
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | lib/connection_tester.rb | 29 | ||||
-rw-r--r-- | spec/lib/connection_tester_spec.rb | 25 |
3 files changed, 22 insertions, 33 deletions
diff --git a/Changelog.md b/Changelog.md index fd0fe3075..cf88f2a13 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ * Upgrade to rails 6.1 [#8366](https://github.com/diaspora/diaspora/pull/8366) * Update the suggested Ruby version to 2.7. If you run into trouble during the update and you followed our installation guides, run `rvm install 2.7`. [#8366](https://github.com/diaspora/diaspora/pull/8366) * Upgrade to bundler 2 [#8366](https://github.com/diaspora/diaspora/pull/8366) +* Stop checking `/.well-known/host-meta`, check for `/.well-known/nodeinfo` instead [#8377](https://github.com/diaspora/diaspora/pull/8377) ## Bug fixes * Fix that no mails were sent after photo export [#8365](https://github.com/diaspora/diaspora/pull/8365) diff --git a/lib/connection_tester.rb b/lib/connection_tester.rb index 5bc58d75b..0e38f10d9 100644 --- a/lib/connection_tester.rb +++ b/lib/connection_tester.rb @@ -1,4 +1,3 @@ - # frozen_string_literal: true class ConnectionTester @@ -97,16 +96,13 @@ class ConnectionTester # * is the SSL certificate valid (only on HTTPS) # * does the server return a successful HTTP status code # * is there a reasonable amount of redirects (3 by default) - # * is there a /.well-known/host-meta (this is needed to work, this can be replaced with a mandatory NodeInfo later) # (can't do a HEAD request, since that's not a defined route in the app) # # @raise [NetFailure, SSLFailure, HTTPFailure] if any of the checks fail # @return [Integer] HTTP status code def request with_http_connection do |http| - capture_response_time { http.get("/") } - response = http.get("/.well-known/host-meta") - handle_http_response(response) + capture_response_time { handle_http_response(http.get("/")) } end rescue HTTPFailure => e raise e @@ -114,8 +110,8 @@ class ConnectionTester raise NetFailure, e.message rescue Faraday::SSLError => e raise SSLFailure, e.message - rescue ArgumentError, FaradayMiddleware::RedirectLimitReached, Faraday::ClientError => e - raise HTTPFailure, e.message + rescue ArgumentError, Faraday::ClientError => e + raise HTTPFailure, "#{e.class}: #{e.message}" rescue StandardError => e unexpected_error(e) end @@ -123,19 +119,21 @@ class ConnectionTester # Try to find out the version of the other servers software. # Assuming the server speaks nodeinfo # - # @raise [NodeInfoFailure] if the document can't be fetched - # or the attempt to parse it failed + # @raise [HTTPFailure] if the document can't be fetched + # @raise [NodeInfoFailure] if the document can't be parsed or is invalid def nodeinfo with_http_connection do |http| ni_resp = http.get(NODEINFO_FRAGMENT) nd_resp = http.get(find_nodeinfo_url(ni_resp.body)) find_software_version(nd_resp.body) end + rescue Faraday::ClientError => e + raise HTTPFailure, "#{e.class}: #{e.message}" rescue NodeInfoFailure => e raise e rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError => e raise NodeInfoFailure, "#{e.class}: #{e.message}" - rescue Faraday::ResourceNotFound, JSON::JSONError => e + rescue JSON::JSONError => e raise NodeInfoFailure, e.message[0..255].encode(Encoding.default_external, undef: :replace) rescue StandardError => e unexpected_error(e) @@ -175,14 +173,11 @@ class ConnectionTester def handle_http_response(response) @result.status_code = Integer(response.status) - if response.success? - raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host + raise HTTPFailure, "unsuccessful response code: #{response.status}" unless response.success? + raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host - @result.reachable = true - @result.ssl = (response.env.url.scheme == "https") - else - raise HTTPFailure, "unsuccessful response code: #{response.status}" - end + @result.reachable = true + @result.ssl = (response.env.url.scheme == "https") end # walk the JSON document, get the actual document location diff --git a/spec/lib/connection_tester_spec.rb b/spec/lib/connection_tester_spec.rb index 01acd20f4..7a11cc0a3 100644 --- a/spec/lib/connection_tester_spec.rb +++ b/spec/lib/connection_tester_spec.rb @@ -47,9 +47,8 @@ describe ConnectionTester do end describe "#request" do - it "performs a successful GET request on '/' and '/.well-known/host-meta'" do + it "performs a successful GET request on '/'" do stub_request(:get, url).to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") tester.request expect(result.rt).to be > -1 @@ -60,27 +59,22 @@ describe ConnectionTester do it "receives a 'normal' 301 redirect" do stub_request(:get, url).to_return(status: 301, headers: {"Location" => "#{url}/redirect"}) stub_request(:get, "#{url}/redirect").to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") tester.request end it "updates ssl after https redirect" do tester = ConnectionTester.new("http://pod.example.com/", result) - stub_request(:get, "http://pod.example.com/").to_return(status: 200, body: "Hello World!") - stub_request(:get, "http://pod.example.com/.well-known/host-meta") - .to_return(status: 301, headers: {"Location" => "#{url}/.well-known/host-meta"}) - stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta") + stub_request(:get, "http://pod.example.com/").to_return(status: 301, headers: {"Location" => url}) + stub_request(:get, url).to_return(status: 200, body: "Hello World!") tester.request expect(result.ssl).to be_truthy end - it "rejects other hostname after redirect redirect" do - stub_request(:get, url).to_return(status: 200, body: "Hello World!") - stub_request(:get, "#{url}/.well-known/host-meta") - .to_return(status: 301, headers: {"Location" => "https://example.com/.well-known/host-meta"}) - stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 200, body: "host-meta") + it "rejects other hostname after redirect" do + stub_request(:get, url).to_return(status: 301, headers: {"Location" => "https://example.com/"}) + stub_request(:get, "https://example.com/").to_return(status: 200, body: "Hello World!") expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure) end @@ -131,10 +125,9 @@ describe ConnectionTester do expect(result.software_version).to eq("diaspora a.b.c.d") end - it "handles a missing nodeinfo document gracefully" do - stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") - .to_return(status: 404, body: "Not Found") - expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure) + it "fails the nodeinfo document is missing" do + stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}").to_return(status: 404, body: "Not Found") + expect { tester.nodeinfo }.to raise_error(ConnectionTester::HTTPFailure) end it "handles a malformed document gracefully" do |