summaryrefslogtreecommitdiff
path: root/spec/unit/network/http/connection_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/network/http/connection_spec.rb')
-rwxr-xr-x[-rw-r--r--]spec/unit/network/http/connection_spec.rb219
1 files changed, 127 insertions, 92 deletions
diff --git a/spec/unit/network/http/connection_spec.rb b/spec/unit/network/http/connection_spec.rb
index a5e6f64ae..ef6ca65d6 100644..100755
--- a/spec/unit/network/http/connection_spec.rb
+++ b/spec/unit/network/http/connection_spec.rb
@@ -11,50 +11,30 @@ describe Puppet::Network::HTTP::Connection do
let (:httpok) { Net::HTTPOK.new('1.1', 200, '') }
context "when providing HTTP connections" do
- after do
- Puppet::Network::HTTP::Connection.instance_variable_set("@ssl_host", nil)
- end
-
context "when initializing http instances" do
- before :each do
- # All of the cert stuff is tested elsewhere
- Puppet::Network::HTTP::Connection.stubs(:cert_setup)
- end
-
it "should return an http instance created with the passed host and port" do
- http = subject.send(:connection)
- http.should be_an_instance_of Net::HTTP
- http.address.should == host
- http.port.should == port
+ conn = Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
+
+ expect(conn.address).to eq(host)
+ expect(conn.port).to eq(port)
end
it "should enable ssl on the http instance by default" do
- http = subject.send(:connection)
- http.should be_use_ssl
- end
+ conn = Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator)
- it "can set ssl using an option" do
- Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false, :verify => Puppet::SSL::Validator.no_validator).send(:connection).should_not be_use_ssl
- Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true, :verify => Puppet::SSL::Validator.no_validator).send(:connection).should be_use_ssl
+ expect(conn).to be_use_ssl
end
- context "proxy and timeout settings should propagate" do
- subject { Puppet::Network::HTTP::Connection.new(host, port, :verify => Puppet::SSL::Validator.no_validator).send(:connection) }
- before :each do
- Puppet[:http_proxy_host] = "myhost"
- Puppet[:http_proxy_port] = 432
- Puppet[:configtimeout] = 120
- end
+ it "can disable ssl using an option" do
+ conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => false, :verify => Puppet::SSL::Validator.no_validator)
- its(:open_timeout) { should == Puppet[:configtimeout] }
- its(:read_timeout) { should == Puppet[:configtimeout] }
- its(:proxy_address) { should == Puppet[:http_proxy_host] }
- its(:proxy_port) { should == Puppet[:http_proxy_port] }
+ expect(conn).to_not be_use_ssl
end
- it "should not set a proxy if the value is 'none'" do
- Puppet[:http_proxy_host] = 'none'
- subject.send(:connection).proxy_address.should be_nil
+ it "can enable ssl using an option" do
+ conn = Puppet::Network::HTTP::Connection.new(host, port, :use_ssl => true, :verify => Puppet::SSL::Validator.no_validator)
+
+ expect(conn).to be_use_ssl
end
it "should raise Puppet::Error when invalid options are specified" do
@@ -96,7 +76,44 @@ describe Puppet::Network::HTTP::Connection do
end
end
- context "when validating HTTPS requests" do
+ class ConstantErrorValidator
+ def initialize(args)
+ @fails_with = args[:fails_with]
+ @error_string = args[:error_string] || ""
+ @peer_certs = args[:peer_certs] || []
+ end
+
+ def setup_connection(connection)
+ connection.stubs(:start).raises(OpenSSL::SSL::SSLError.new(@fails_with))
+ end
+
+ def peer_certs
+ @peer_certs
+ end
+
+ def verify_errors
+ [@error_string]
+ end
+ end
+
+ class NoProblemsValidator
+ def initialize(cert)
+ @cert = cert
+ end
+
+ def setup_connection(connection)
+ end
+
+ def peer_certs
+ [@cert]
+ end
+
+ def verify_errors
+ []
+ end
+ end
+
+ shared_examples_for 'ssl verifier' do
include PuppetSpec::Files
let (:host) { "my_server" }
@@ -117,11 +134,11 @@ describe Puppet::Network::HTTP::Connection do
Puppet[:confdir] = tmpdir('conf')
connection = Puppet::Network::HTTP::Connection.new(
- host, port,
- :verify => ConstantErrorValidator.new(
- :fails_with => 'hostname was not match with server certificate',
- :peer_certs => [Puppet::SSL::CertificateAuthority.new.generate(
- 'not_my_server', :dns_alt_names => 'foo,bar,baz')]))
+ host, port,
+ :verify => ConstantErrorValidator.new(
+ :fails_with => 'hostname was not match with server certificate',
+ :peer_certs => [Puppet::SSL::CertificateAuthority.new.generate(
+ 'not_my_server', :dns_alt_names => 'foo,bar,baz')]))
expect do
connection.get('request')
@@ -150,86 +167,104 @@ describe Puppet::Network::HTTP::Connection do
host, port,
:verify => NoProblemsValidator.new(cert))
+ Net::HTTP.any_instance.stubs(:start)
Net::HTTP.any_instance.stubs(:request).returns(httpok)
connection.expects(:warn_if_near_expiration).with(cert)
connection.get('request')
end
+ end
- class ConstantErrorValidator
- def initialize(args)
- @fails_with = args[:fails_with]
- @error_string = args[:error_string] || ""
- @peer_certs = args[:peer_certs] || []
- end
+ context "when using single use HTTPS connections" do
+ it_behaves_like 'ssl verifier' do
+ end
+ end
- def setup_connection(connection)
- connection.stubs(:request).with do
- true
- end.raises(OpenSSL::SSL::SSLError.new(@fails_with))
+ context "when using persistent HTTPS connections" do
+ around :each do |example|
+ pool = Puppet::Network::HTTP::Pool.new
+ Puppet.override(:http_pool => pool) do
+ example.run
end
+ pool.close
+ end
- def peer_certs
- @peer_certs
- end
+ it_behaves_like 'ssl verifier' do
+ end
+ end
- def verify_errors
- [@error_string]
- end
+ context "when response is a redirect" do
+ let (:site) { Puppet::Network::HTTP::Site.new('http', 'my_server', 8140) }
+ let (:other_site) { Puppet::Network::HTTP::Site.new('http', 'redirected', 9292) }
+ let (:other_path) { "other-path" }
+ let (:verify) { Puppet::SSL::Validator.no_validator }
+ let (:subject) { Puppet::Network::HTTP::Connection.new(site.host, site.port, :use_ssl => false, :verify => verify) }
+ let (:httpredirection) do
+ response = Net::HTTPFound.new('1.1', 302, 'Moved Temporarily')
+ response['location'] = "#{other_site.addr}/#{other_path}"
+ response.stubs(:read_body).returns("This resource has moved")
+ response
end
- class NoProblemsValidator
- def initialize(cert)
- @cert = cert
- end
+ def create_connection(site, options)
+ options[:use_ssl] = site.use_ssl?
+ Puppet::Network::HTTP::Connection.new(site.host, site.port, options)
+ end
- def setup_connection(connection)
- end
+ it "should redirect to the final resource location" do
+ http = stub('http')
+ http.stubs(:request).returns(httpredirection).then.returns(httpok)
- def peer_certs
- [@cert]
- end
+ seq = sequence('redirection')
+ pool = Puppet.lookup(:http_pool)
+ pool.expects(:with_connection).with(site, anything).yields(http).in_sequence(seq)
+ pool.expects(:with_connection).with(other_site, anything).yields(http).in_sequence(seq)
- def verify_errors
- []
- end
+ conn = create_connection(site, :verify => verify)
+ conn.get('/foo')
end
- end
- context "when response is a redirect" do
- let (:other_host) { "redirected" }
- let (:other_port) { 9292 }
- let (:other_path) { "other-path" }
- let (:subject) { Puppet::Network::HTTP::Connection.new("my_server", 8140, :use_ssl => false, :verify => Puppet::SSL::Validator.no_validator) }
- let (:httpredirection) { Net::HTTPFound.new('1.1', 302, 'Moved Temporarily') }
+ def expects_redirection(conn, &block)
+ http = stub('http')
+ http.stubs(:request).returns(httpredirection)
- before :each do
- httpredirection['location'] = "http://#{other_host}:#{other_port}/#{other_path}"
- httpredirection.stubs(:read_body).returns("This resource has moved")
+ pool = Puppet.lookup(:http_pool)
+ pool.expects(:with_connection).with(site, anything).yields(http)
+ pool
+ end
- socket = stub_everything("socket")
- TCPSocket.stubs(:open).returns(socket)
+ def expects_limit_exceeded(conn)
+ expect {
+ conn.get('/')
+ }.to raise_error(Puppet::Network::HTTP::RedirectionLimitExceededException)
+ end
- Net::HTTP::Get.any_instance.stubs(:exec).returns("")
- Net::HTTP::Post.any_instance.stubs(:exec).returns("")
+ it "should not redirect when the limit is 0" do
+ conn = create_connection(site, :verify => verify, :redirect_limit => 0)
+
+ pool = expects_redirection(conn)
+ pool.expects(:with_connection).with(other_site, anything).never
+
+ expects_limit_exceeded(conn)
end
- it "should redirect to the final resource location" do
- httpok.stubs(:read_body).returns(:body)
- Net::HTTPResponse.stubs(:read_new).returns(httpredirection).then.returns(httpok)
+ it "should redirect only once" do
+ conn = create_connection(site, :verify => verify, :redirect_limit => 1)
+
+ pool = expects_redirection(conn)
+ pool.expects(:with_connection).with(other_site, anything).once
- subject.get("/foo").body.should == :body
- subject.port.should == other_port
- subject.address.should == other_host
+ expects_limit_exceeded(conn)
end
- it "should raise an error after too many redirections" do
- Net::HTTPResponse.stubs(:read_new).returns(httpredirection)
+ it "should raise an exception when the redirect limit is exceeded" do
+ conn = create_connection(site, :verify => verify, :redirect_limit => 3)
- expect {
- subject.get("/foo")
- }.to raise_error(Puppet::Network::HTTP::RedirectionLimitExceededException)
+ pool = expects_redirection(conn)
+ pool.expects(:with_connection).with(other_site, anything).times(3)
+
+ expects_limit_exceeded(conn)
end
end