From c649295673ff6fd39c6d56bae85987866e7fa86c Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Tue, 5 Jun 2018 19:01:20 -0700 Subject: [PATCH] Refactor server SSL identification --- lib/capybara/server.rb | 25 ++++------------------ lib/capybara/server/checker.rb | 38 ++++++++++++++++++++++++++++++++++ spec/server_spec.rb | 1 - 3 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 lib/capybara/server/checker.rb diff --git a/lib/capybara/server.rb b/lib/capybara/server.rb index ed924122..02f5bc08 100644 --- a/lib/capybara/server.rb +++ b/lib/capybara/server.rb @@ -5,6 +5,7 @@ require 'net/http' require 'rack' require 'capybara/server/middleware' require 'capybara/server/animation_disabler' +require 'capybara/server/checker' module Capybara class Server @@ -23,10 +24,10 @@ module Capybara @server_thread = nil # suppress warnings @host = deprecated_options[1] || host @reportable_errors = deprecated_options[2] || reportable_errors - @using_ssl = false @port = deprecated_options[0] || port @port ||= Capybara::Server.ports[port_key] @port ||= find_available_port(host) + @checker = Checker.new(@host, @port) end def reset_error! @@ -38,22 +39,12 @@ module Capybara end def using_ssl? - @using_ssl + @checker.ssl? end def responsive? return false if @server_thread&.join(0) - - begin - res = if !using_ssl? - http_connect - else - https_connect - end - rescue EOFError, Net::ReadTimeout - res = https_connect - @using_ssl = true - end + res = @checker.request { |http| http.get('/__identify__') } if res.is_a?(Net::HTTPSuccess) || res.is_a?(Net::HTTPRedirection) return res.body == app.object_id.to_s @@ -94,14 +85,6 @@ module Capybara private - def http_connect - Net::HTTP.start(host, port, read_timeout: 2) { |http| http.get('/__identify__') } - end - - def https_connect - Net::HTTP.start(host, port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) { |http| http.get('/__identify__') } - end - def middleware @middleware ||= Middleware.new(app, @reportable_errors, @extra_middleware) end diff --git a/lib/capybara/server/checker.rb b/lib/capybara/server/checker.rb new file mode 100644 index 00000000..e9285404 --- /dev/null +++ b/lib/capybara/server/checker.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Capybara + class Server + class Checker + def initialize(host, port) + @host, @port = host, port + @ssl = false + end + + def request(&block) + ssl? ? https_request(&block) : http_request(&block) + rescue EOFError, Net::ReadTimeout + res = https_request(&block) + @ssl = true + res + end + + def ssl? + @ssl + end + + private + + def http_request(&block) + Net::HTTP.start(@host, @port, read_timeout: 2, &block) + end + + def https_request(&block) + Net::HTTP.start(@host, @port, ssl_options, &block) + end + + def ssl_options + { use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE } + end + end + end +end diff --git a/spec/server_spec.rb b/spec/server_spec.rb index 2193fb70..58700a19 100644 --- a/spec/server_spec.rb +++ b/spec/server_spec.rb @@ -219,7 +219,6 @@ RSpec.describe Capybara::Server do it "should attempt an HTTPS connection if HTTP connection returns #{err}" do app = -> { [200, {}, ['Hello, world']] } ordered_errors = [Errno::ECONNREFUSED, err] - # allow(Net::HTTP).to receive(:start).with(anything, anything, hash_excluding(:use_ssl)).and_yield { raise Errno::ECONNREFUSED } allow(Net::HTTP).to receive(:start).with(anything, anything, hash_excluding(:use_ssl)) do raise ordered_errors.shift end