mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Support configuring the puma server to use SSL
This commit is contained in:
parent
bbec20f91d
commit
170bc99d68
6 changed files with 123 additions and 8 deletions
|
@ -61,10 +61,14 @@ module Capybara
|
|||
|
||||
attr_reader :app, :port, :host
|
||||
|
||||
def initialize(app, port = Capybara.server_port, host = Capybara.server_host, server_errors = Capybara.server_errors)
|
||||
def initialize(app, *deprecated_options, port: Capybara.server_port, host: Capybara.server_host, reportable_errors: Capybara.server_errors)
|
||||
warn "Positional arguments, other than the application, to Server#new are deprecated, please use keyword arguments" unless deprecated_options.empty?
|
||||
@app = app
|
||||
@server_thread = nil # suppress warnings
|
||||
@host, @port, @server_errors = host, port, server_errors
|
||||
@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)
|
||||
end
|
||||
|
@ -77,10 +81,23 @@ module Capybara
|
|||
middleware.error
|
||||
end
|
||||
|
||||
def using_ssl?
|
||||
@using_ssl
|
||||
end
|
||||
|
||||
def responsive?
|
||||
return false if @server_thread && @server_thread.join(0)
|
||||
|
||||
res = Net::HTTP.start(host, port) { |http| http.get('/__identify__') }
|
||||
begin
|
||||
res = if !@using_ssl
|
||||
http_connect
|
||||
else
|
||||
https_connect
|
||||
end
|
||||
rescue EOFError, Net::ReadTimeout
|
||||
res = https_connect
|
||||
@using_ssl = true
|
||||
end
|
||||
|
||||
if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
|
||||
return res.body == app.object_id.to_s
|
||||
|
@ -121,8 +138,16 @@ 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, @server_errors)
|
||||
@middleware ||= Middleware.new(app, @reportable_errors)
|
||||
end
|
||||
|
||||
def port_key
|
||||
|
|
|
@ -84,7 +84,7 @@ module Capybara
|
|||
yield config
|
||||
end
|
||||
@server = if config.run_server and @app and driver.needs_server?
|
||||
Capybara::Server.new(@app, config.server_port, config.server_host, config.server_errors).boot
|
||||
Capybara::Server.new(@app, port: config.server_port, host: config.server_host, reportable_errors: config.server_errors).boot
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
@ -249,7 +249,7 @@ module Capybara
|
|||
visit_uri = ::Addressable::URI.parse(visit_uri.to_s)
|
||||
|
||||
uri_base = if @server
|
||||
::Addressable::URI.parse(config.app_host || "http://#{@server.host}:#{@server.port}")
|
||||
::Addressable::URI.parse(config.app_host || "http#{'s' if @server.using_ssl?}://#{@server.host}:#{@server.port}")
|
||||
else
|
||||
config.app_host && ::Addressable::URI.parse(config.app_host)
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ RSpec.describe Capybara do
|
|||
|
||||
it "should default to a proc that calls run_default_server" do
|
||||
mock_app = Object.new
|
||||
allow(Capybara).to receive(:run_default_server)
|
||||
allow(Capybara).to receive(:run_default_server).and_return(true)
|
||||
Capybara.server.call(mock_app, 8000)
|
||||
expect(Capybara).to have_received(:run_default_server).with(mock_app, 8000)
|
||||
end
|
||||
|
|
25
spec/fixtures/certificate.pem
vendored
Normal file
25
spec/fixtures/certificate.pem
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEITCCAwmgAwIBAgIJALROkwd1gZHQMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIEwJDQTERMA8GA1UEChMIQ2FweWJhcmExFjAUBgNVBAMT
|
||||
DWNhcHliYXJhLnRlc3QxITAfBgkqhkiG9w0BCQEWEnR3YWxwb2xlQGdtYWlsLmNv
|
||||
bTAeFw0xODA1MDEyMDI5NDVaFw0yODA0MjgyMDI5NDVaMGgxCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIEwJDQTERMA8GA1UEChMIQ2FweWJhcmExFjAUBgNVBAMTDWNhcHli
|
||||
YXJhLnRlc3QxITAfBgkqhkiG9w0BCQEWEnR3YWxwb2xlQGdtYWlsLmNvbTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL7icqMv9uApxRXlcIQ3hSEfmULk
|
||||
7CLT1aUAjEmTiqy8TkFqOeSuA3elnbVBhOW+emrb1uUyje20LvEOHbqYYw90ezlV
|
||||
jqNWUapawqjxb+q7KVNpA5uDCtOHIC/1Z1kxQ+yZP/8St4SvnLGUMsUhu0h+ywJa
|
||||
iGZ2xy8wdfjABUiUImRESdNkT7Xs0wxQGY0/FZ4K5Sec4kroOuvdxKKhyf5Js5xS
|
||||
NRv2tXSMWlKHbYEvYzsVtFgv/4GjqN4wVvbfJmsS8thcyrSYSMN7eE0R6dcbJaLM
|
||||
P/GTiw669zPJP164K84QoabLClgwyG+7mqjm7jutq9qXipwyrGsf/WR5fkUCAwEA
|
||||
AaOBzTCByjAdBgNVHQ4EFgQU4ut9c0oB2OGMlN/nvn0Y7twBzJowgZoGA1UdIwSB
|
||||
kjCBj4AU4ut9c0oB2OGMlN/nvn0Y7twBzJqhbKRqMGgxCzAJBgNVBAYTAlVTMQsw
|
||||
CQYDVQQIEwJDQTERMA8GA1UEChMIQ2FweWJhcmExFjAUBgNVBAMTDWNhcHliYXJh
|
||||
LnRlc3QxITAfBgkqhkiG9w0BCQEWEnR3YWxwb2xlQGdtYWlsLmNvbYIJALROkwd1
|
||||
gZHQMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAANtqdDrdehBt20s
|
||||
IVOsVzOp+tJI8pn6G62WJcZWGsvLLfx6Y6eJSP24r5NW4v39cqCgE76J2znzKxeo
|
||||
VIShAJ1SLodR0GwzFGsl3TVKVoce6gBWZNXgkZyJTNqKGWeme8CH1EG3TqYlcybt
|
||||
EXWLQ6wKndD+uHJIfqUy7HfaUv+TghJGLkv8QYqcAWILQko4xqZ1NULDQ2uhjxei
|
||||
oaQlK9teHlVaH87dONesAg3f5rh9j6nvzGiC/T8ycdEhn/DxJMxRS2+mVZqKkk7U
|
||||
60+e9Foc6qTW8UaMShIFYMspoRnr9baBxzxh9V9LZznwqVTf3vuEIck2l2j2KL/R
|
||||
SOBenCM=
|
||||
-----END CERTIFICATE-----
|
27
spec/fixtures/key.pem
vendored
Normal file
27
spec/fixtures/key.pem
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAvuJyoy/24CnFFeVwhDeFIR+ZQuTsItPVpQCMSZOKrLxOQWo5
|
||||
5K4Dd6WdtUGE5b56atvW5TKN7bQu8Q4duphjD3R7OVWOo1ZRqlrCqPFv6rspU2kD
|
||||
m4MK04cgL/VnWTFD7Jk//xK3hK+csZQyxSG7SH7LAlqIZnbHLzB1+MAFSJQiZERJ
|
||||
02RPtezTDFAZjT8VngrlJ5ziSug6693EoqHJ/kmznFI1G/a1dIxaUodtgS9jOxW0
|
||||
WC//gaOo3jBW9t8maxLy2FzKtJhIw3t4TRHp1xslosw/8ZOLDrr3M8k/XrgrzhCh
|
||||
pssKWDDIb7uaqObuO62r2peKnDKsax/9ZHl+RQIDAQABAoIBABhZepYmgC+IJIPu
|
||||
iLPVAT6AcWR/H0AyFYa+0yZvk7kFLFZb3pa1O+v/TGbavMEx0xvef0Mtd71ixrop
|
||||
OtGarshB65Ycu91KHZDFkx9J7STcSyFAvB0SUkc5bXmwrEZMaoW75tX65T4fyLU+
|
||||
WlubOfC9e9gJBG1NqYrze5kHpaTkR8pBaSxECns5y2HLaMvs1t1kK7snqtGHFRAb
|
||||
deAUl0ONENaO6PF797yM3bsIEgnljdKvaVP3kYq/eAzH4jyw+qG/xq0bZ+nalJzM
|
||||
IL7xRSR/Yak7WZ3QUh99t3dng/z3De4yvhBLq/mc2mIVvt7aERPo/aDG4SrmQ9Jw
|
||||
f1GUT+ECgYEA+i96w2zPHkq0djuuhNaa/R0vybD9hVCdB7enQ8skBzQAQyhp9X9W
|
||||
by38VAbFRVIMrzdfbvwSFrE3Nd9BvyLWl16G+MVu+hq0jhM9p44a62vXvfgQmfFh
|
||||
iXyGkzCTufeLEzOFnP8S+ezacodK1hbQTjllUndn6NUhXcbfozTPfx8CgYEAw1Il
|
||||
xqfU7NkVX6UP/FvTx9aBKqwrD8YOPn9nj26Q45zVbmHJZZIvywlsMDCiJ6JJawEa
|
||||
GSkiZTDpypEvS/2UtLEY0zfbSbQGkBTnagHIFAuVh0AD1EP+kCcnrxA5Vjr8v0WE
|
||||
B0HBfMgoZxa8rmHMpPhrlCCo1ectRgu+dgzEKhsCgYAQ17lwBpc69tSHUSVClCAD
|
||||
AkABWAT5QKARsO91xOs8AOgznTjk6hmrinD+RyZosEliUlv+YMHm/S82VT1b3MCN
|
||||
mDOF8+SwubOGDQ2NhieRycTQaS7U7kcetl9o8VBAqMWYGVPZaeKhKKzcIPeMyiRj
|
||||
38FOd/Nq3U5NveG4XwnJCQKBgGrzmnfTAsbGf+uliMFYzviIPqZNLC8w9i/Gt8BU
|
||||
fMYF5ODSbuNNTxpQiItCtigZtzX+nnnUil76j6o6IbnsmvbuWneeCFetWkKfD7B+
|
||||
VT6UsUYkCXS73rK0nghATAUpu6hIumj22qonN+hrDNo390UGOnIcCBdIxQOr/pjJ
|
||||
mMitAoGAB3tFzlzZHpCE38IqdHL7CKIML9cYJSOm07nFIEUAKN2bUHGsvMH/tMS1
|
||||
I3hyeHxMmYCrOLn7xLqiOVgRjbYS9JiQVdDojqeSvvnLCtY9/lHWi50pqbPfwyfK
|
||||
Og6QoFyxjBEsoSilc6dai58VTO6ufhoJXbXX9PcIl7le4dVPnzE=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -51,7 +51,7 @@ RSpec.describe Capybara::Server do
|
|||
|
||||
it "should use given port" do
|
||||
@app = proc { |_env| [200, {}, ["Hello Server!"]] }
|
||||
@server = Capybara::Server.new(@app, 22790).boot
|
||||
@server = Capybara::Server.new(@app, port: 22790).boot
|
||||
|
||||
@res = Net::HTTP.start(@server.host, 22790) { |http| http.get('/') }
|
||||
expect(@res.body).to include('Hello Server')
|
||||
|
@ -73,6 +73,28 @@ RSpec.describe Capybara::Server do
|
|||
expect(@res2.body).to include('Hello Second Server')
|
||||
end
|
||||
|
||||
it "should support SSL" do
|
||||
begin
|
||||
key = File.join(Dir.pwd, "spec", "fixtures", "key.pem")
|
||||
cert = File.join(Dir.pwd, "spec", "fixtures", "certificate.pem")
|
||||
Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
|
||||
app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
|
||||
server = Capybara::Server.new(app).boot
|
||||
|
||||
expect do
|
||||
Net::HTTP.start(server.host, server.port) { |http| http.get('/__idntify__') }
|
||||
end.to raise_error(EOFError)
|
||||
|
||||
res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
|
||||
https.get('/')
|
||||
end
|
||||
|
||||
expect(res.body).to include('Hello SSL Server!')
|
||||
ensure
|
||||
Capybara.server = :default
|
||||
end
|
||||
end
|
||||
|
||||
context "When Capybara.reuse_server is true" do
|
||||
before do
|
||||
@old_reuse_server = Capybara.reuse_server
|
||||
|
@ -193,6 +215,22 @@ RSpec.describe Capybara::Server do
|
|||
expect(server.responsive?).to eq false
|
||||
end
|
||||
|
||||
[EOFError, Net::ReadTimeout].each do |err|
|
||||
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
|
||||
response = Net::HTTPSuccess.allocate
|
||||
allow(response).to receive(:body).and_return app.object_id.to_s
|
||||
allow(Net::HTTP).to receive(:start).with(anything, anything, hash_including(use_ssl: true)).and_return(response).once
|
||||
Capybara::Server.new(app).boot
|
||||
expect(Net::HTTP).to have_received(:start).exactly(3).times
|
||||
end
|
||||
end
|
||||
|
||||
def start_request(server, wait_time)
|
||||
# Start request, but don't wait for it to finish
|
||||
socket = TCPSocket.new(server.host, server.port)
|
||||
|
|
Loading…
Reference in a new issue