Class: ConnectionTester
- Inherits:
-
Object
- Object
- ConnectionTester
- Includes:
- Diaspora::Logging
- Defined in:
- lib/connection_tester.rb
Defined Under Namespace
Classes: AddressFailure, DNSFailure, Failure, HTTPFailure, NetFailure, NodeInfoFailure, Result, SSLFailure
Constant Summary collapse
- NODEINFO_FRAGMENT =
"/.well-known/nodeinfo"
Class Method Summary collapse
-
.check(url) ⇒ Result
Test the reachability of a server by the given HTTP/S URL.
Instance Method Summary collapse
-
#initialize(url, result = Result.new) ⇒ ConnectionTester
constructor
A new instance of ConnectionTester.
-
#nodeinfo ⇒ Object
Try to find out the version of the other servers software.
-
#request ⇒ Integer
Perform a HTTP GET request to determine the following information * is the host reachable * is port 80/443 open * 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) (can’t do a HEAD request, since that’s not a defined route in the app).
-
#resolve ⇒ Object
Perform the DNS query, the IP address will be stored in the result.
Constructor Details
#initialize(url, result = Result.new) ⇒ ConnectionTester
Returns a new instance of ConnectionTester.
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/connection_tester.rb', line 68 def initialize(url, result=Result.new) @url ||= url @result ||= result @uri ||= URI.parse(@url) raise AddressFailure, "invalid protocol: '#{@uri.scheme.upcase}'" unless http_uri?(@uri) rescue AddressFailure => e raise e rescue URI::InvalidURIError => e raise AddressFailure, e. rescue StandardError => e unexpected_error(e) end |
Class Method Details
.check(url) ⇒ Result
Test the reachability of a server by the given HTTP/S URL. In the first step, a DNS query is performed to check whether the given name even resolves correctly. The second step is to send a HTTP request and look at the returned status code or any returned errors. This function isn’t intended to check for the availability of a specific page, instead a GET request is sent to the root directory of the server. In the third step an attempt is made to determine the software version used on the server, via the nodeinfo page.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/connection_tester.rb', line 25 def check(url) result = Result.new begin ct = ConnectionTester.new(url, result) # test DNS resolving ct.resolve # test HTTP request ct.request # test for the diaspora* version ct.nodeinfo rescue Failure => e result_from_failure(result, e) end result.freeze end |
Instance Method Details
#nodeinfo ⇒ Object
Try to find out the version of the other servers software. Assuming the server speaks nodeinfo
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/connection_tester.rb', line 123 def nodeinfo with_http_connection do |http| ni_resp = http.get(NODEINFO_FRAGMENT) ni_urls = find_nodeinfo_urls(ni_resp.body) raise NodeInfoFailure, "No supported NodeInfo version found" if ni_urls.empty? version, url = ni_urls.max find_software_version(version, http.get(url).body) end rescue Faraday::ClientError => e raise HTTPFailure, "#{e.class}: #{e.}" rescue NodeInfoFailure => e raise e rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError, Faraday::TimeoutError => e raise NodeInfoFailure, "#{e.class}: #{e.}" rescue JSON::JSONError => e raise NodeInfoFailure, e.[0..255].encode(Encoding.default_external, undef: :replace) rescue StandardError => e unexpected_error(e) end |
#request ⇒ Integer
Perform a HTTP GET request to determine the following information
-
is the host reachable
-
is port 80/443 open
-
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)
(can’t do a HEAD request, since that’s not a defined route in the app)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/connection_tester.rb', line 102 def request with_http_connection do |http| capture_response_time { handle_http_response(http.get("/")) } end rescue HTTPFailure => e raise e rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e raise NetFailure, e. rescue Faraday::SSLError => e raise SSLFailure, e. rescue ArgumentError, Faraday::ClientError, Faraday::ServerError => e raise HTTPFailure, "#{e.class}: #{e.}" rescue StandardError => e unexpected_error(e) end |
#resolve ⇒ Object
Perform the DNS query, the IP address will be stored in the result
84 85 86 87 88 89 90 |
# File 'lib/connection_tester.rb', line 84 def resolve @result.ip = IPSocket.getaddress(@uri.host) rescue SocketError => e raise DNSFailure, "'#{@uri.host}' - #{e.}" rescue StandardError => e unexpected_error(e) end |