2013-07-09 19:21:36 -04:00
|
|
|
require 'rubygems/test_case'
|
|
|
|
require 'rubygems/request'
|
|
|
|
require 'ostruct'
|
2014-02-03 19:48:31 -05:00
|
|
|
require 'base64'
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
class TestGemRequest < Gem::TestCase
|
|
|
|
|
2014-02-03 19:48:31 -05:00
|
|
|
CA_CERT_FILE = cert_path 'ca'
|
|
|
|
CHILD_CERT = load_cert 'child'
|
|
|
|
PUBLIC_CERT = load_cert 'public'
|
|
|
|
PUBLIC_CERT_FILE = cert_path 'public'
|
|
|
|
SSL_CERT = load_cert 'ssl'
|
|
|
|
|
2013-07-09 19:21:36 -04:00
|
|
|
def setup
|
|
|
|
@proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY]
|
|
|
|
@old_proxies = @proxies.map {|k| ENV[k] }
|
|
|
|
@proxies.each {|k| ENV[k] = nil }
|
|
|
|
|
|
|
|
super
|
|
|
|
|
|
|
|
@proxy_uri = "http://localhost:1234"
|
2013-09-18 17:29:41 -04:00
|
|
|
@uri = URI('http://example')
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
@request = Gem::Request.new @uri, nil, nil, nil
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
super
|
|
|
|
Gem.configuration[:http_proxy] = nil
|
|
|
|
@proxies.each_with_index {|k, i| ENV[k] = @old_proxies[i] }
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_initialize_proxy
|
|
|
|
proxy_uri = 'http://proxy.example.com'
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
request = Gem::Request.new @uri, nil, nil, proxy_uri
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_equal proxy_uri, request.proxy_uri.to_s
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_initialize_proxy_URI
|
|
|
|
proxy_uri = 'http://proxy.example.com'
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
request = Gem::Request.new @uri, nil, nil, URI(proxy_uri)
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_equal proxy_uri, request.proxy_uri.to_s
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_initialize_proxy_ENV
|
|
|
|
ENV['http_proxy'] = @proxy_uri
|
|
|
|
ENV['http_proxy_user'] = 'foo'
|
|
|
|
ENV['http_proxy_pass'] = 'bar'
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
request = Gem::Request.new @uri, nil, nil, nil
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
proxy = request.proxy_uri
|
|
|
|
|
|
|
|
assert_equal 'foo', proxy.user
|
|
|
|
assert_equal 'bar', proxy.password
|
|
|
|
end
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
def test_initialize_proxy_ENV_https
|
|
|
|
ENV['https_proxy'] = @proxy_uri
|
|
|
|
|
|
|
|
request = Gem::Request.new URI('https://example'), nil, nil, nil
|
|
|
|
|
|
|
|
proxy = request.proxy_uri
|
|
|
|
|
|
|
|
assert_equal URI(@proxy_uri), proxy
|
|
|
|
end
|
|
|
|
|
2014-02-03 19:48:31 -05:00
|
|
|
def test_configure_connection_for_https
|
|
|
|
connection = Net::HTTP.new 'localhost', 443
|
|
|
|
|
|
|
|
request = Gem::Request.new URI('https://example'), nil, nil, nil
|
|
|
|
|
|
|
|
def request.add_rubygems_trusted_certs store
|
|
|
|
store.add_cert TestGemRequest::PUBLIC_CERT
|
|
|
|
end
|
|
|
|
|
|
|
|
request.configure_connection_for_https connection
|
|
|
|
|
|
|
|
cert_store = connection.cert_store
|
|
|
|
|
|
|
|
assert cert_store.verify CHILD_CERT
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_configure_connection_for_https_ssl_ca_cert
|
|
|
|
ssl_ca_cert, Gem.configuration.ssl_ca_cert =
|
|
|
|
Gem.configuration.ssl_ca_cert, CA_CERT_FILE
|
|
|
|
|
|
|
|
connection = Net::HTTP.new 'localhost', 443
|
|
|
|
|
|
|
|
request = Gem::Request.new URI('https://example'), nil, nil, nil
|
|
|
|
|
|
|
|
def request.add_rubygems_trusted_certs store
|
|
|
|
store.add_cert TestGemRequest::PUBLIC_CERT
|
|
|
|
end
|
|
|
|
|
|
|
|
request.configure_connection_for_https connection
|
|
|
|
|
|
|
|
cert_store = connection.cert_store
|
|
|
|
|
|
|
|
assert cert_store.verify CHILD_CERT
|
|
|
|
assert cert_store.verify SSL_CERT
|
|
|
|
ensure
|
|
|
|
Gem.configuration.ssl_ca_cert = ssl_ca_cert
|
|
|
|
end
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
def test_get_proxy_from_env_fallback
|
|
|
|
ENV['http_proxy'] = @proxy_uri
|
|
|
|
|
|
|
|
proxy = @request.get_proxy_from_env 'https'
|
|
|
|
|
|
|
|
assert_equal URI(@proxy_uri), proxy
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_get_proxy_from_env_https
|
|
|
|
ENV['https_proxy'] = @proxy_uri
|
|
|
|
|
|
|
|
proxy = @request.get_proxy_from_env 'https'
|
|
|
|
|
|
|
|
assert_equal URI(@proxy_uri), proxy
|
|
|
|
end
|
|
|
|
|
2013-07-09 19:21:36 -04:00
|
|
|
def test_get_proxy_from_env_domain
|
|
|
|
ENV['http_proxy'] = @proxy_uri
|
|
|
|
ENV['http_proxy_user'] = 'foo\user'
|
|
|
|
ENV['http_proxy_pass'] = 'my bar'
|
|
|
|
|
|
|
|
proxy = @request.get_proxy_from_env
|
|
|
|
|
|
|
|
assert_equal 'foo\user', Gem::UriFormatter.new(proxy.user).unescape
|
|
|
|
assert_equal 'my bar', Gem::UriFormatter.new(proxy.password).unescape
|
|
|
|
end
|
|
|
|
|
2013-10-15 20:14:16 -04:00
|
|
|
def test_get_proxy_from_env_escape
|
|
|
|
ENV['http_proxy'] = @proxy_uri
|
|
|
|
ENV['http_proxy_user'] = 'foo@user'
|
|
|
|
ENV['http_proxy_pass'] = 'my@bar'
|
|
|
|
|
|
|
|
proxy = @request.get_proxy_from_env
|
|
|
|
|
|
|
|
assert_equal 'foo%40user', proxy.user
|
|
|
|
assert_equal 'my%40bar', proxy.password
|
|
|
|
end
|
|
|
|
|
2013-07-09 19:21:36 -04:00
|
|
|
def test_get_proxy_from_env_normalize
|
|
|
|
ENV['HTTP_PROXY'] = 'fakeurl:12345'
|
|
|
|
|
|
|
|
assert_equal 'http://fakeurl:12345', @request.get_proxy_from_env.to_s
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_get_proxy_from_env_empty
|
|
|
|
ENV['HTTP_PROXY'] = ''
|
|
|
|
ENV.delete 'http_proxy'
|
|
|
|
|
|
|
|
assert_nil @request.get_proxy_from_env
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_fetch
|
|
|
|
uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
|
|
|
|
@request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil)
|
|
|
|
util_stub_connection_for :body => :junk, :code => 200
|
|
|
|
|
|
|
|
response = @request.fetch
|
|
|
|
|
|
|
|
assert_equal 200, response.code
|
|
|
|
assert_equal :junk, response.body
|
|
|
|
end
|
|
|
|
|
2014-02-03 19:48:31 -05:00
|
|
|
def test_fetch_basic_auth
|
|
|
|
uri = URI.parse "https://user:pass@example.rubygems/specs.#{Gem.marshal_version}"
|
|
|
|
@request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil)
|
|
|
|
conn = util_stub_connection_for :body => :junk, :code => 200
|
|
|
|
|
|
|
|
@request.fetch
|
|
|
|
|
|
|
|
auth_header = conn.payload['Authorization']
|
|
|
|
|
|
|
|
assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_fetch_basic_auth_encoded
|
|
|
|
uri = URI.parse "https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}"
|
|
|
|
@request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil)
|
|
|
|
conn = util_stub_connection_for :body => :junk, :code => 200
|
|
|
|
|
|
|
|
@request.fetch
|
|
|
|
|
|
|
|
auth_header = conn.payload['Authorization']
|
|
|
|
|
|
|
|
assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header
|
|
|
|
end
|
|
|
|
|
2013-07-09 19:21:36 -04:00
|
|
|
def test_fetch_head
|
|
|
|
uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
|
|
|
|
@request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil)
|
|
|
|
util_stub_connection_for :body => '', :code => 200
|
|
|
|
|
|
|
|
response = @request.fetch
|
|
|
|
|
|
|
|
assert_equal 200, response.code
|
|
|
|
assert_equal '', response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_fetch_unmodified
|
|
|
|
uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}"
|
2013-10-15 20:14:16 -04:00
|
|
|
t = Time.utc(2013, 1, 2, 3, 4, 5)
|
2013-07-09 19:21:36 -04:00
|
|
|
@request = Gem::Request.new(uri, Net::HTTP::Get, t, nil)
|
|
|
|
conn = util_stub_connection_for :body => '', :code => 304
|
|
|
|
|
|
|
|
response = @request.fetch
|
|
|
|
|
|
|
|
assert_equal 304, response.code
|
|
|
|
assert_equal '', response.body
|
|
|
|
|
2013-10-15 20:14:16 -04:00
|
|
|
modified_header = conn.payload['if-modified-since']
|
|
|
|
|
|
|
|
assert_equal 'Wed, 02 Jan 2013 03:04:05 GMT', modified_header
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua
|
|
|
|
assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua
|
|
|
|
assert_match %r% #{Regexp.escape Gem::Platform.local.to_s} %, ua
|
|
|
|
assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}%, ua
|
|
|
|
assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE} %, ua
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent_engine
|
|
|
|
util_save_version
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
|
|
|
|
Object.send :const_set, :RUBY_ENGINE, 'vroom'
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r%\) vroom%, ua
|
|
|
|
ensure
|
|
|
|
util_restore_version
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent_engine_ruby
|
|
|
|
util_save_version
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
|
|
|
|
Object.send :const_set, :RUBY_ENGINE, 'ruby'
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r%\)%, ua
|
|
|
|
ensure
|
|
|
|
util_restore_version
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent_patchlevel
|
|
|
|
util_save_version
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_PATCHLEVEL
|
|
|
|
Object.send :const_set, :RUBY_PATCHLEVEL, 5
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r% patchlevel 5\)%, ua
|
|
|
|
ensure
|
|
|
|
util_restore_version
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent_revision
|
|
|
|
util_save_version
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_PATCHLEVEL
|
|
|
|
Object.send :const_set, :RUBY_PATCHLEVEL, -1
|
|
|
|
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
|
|
|
|
Object.send :const_set, :RUBY_REVISION, 6
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r% revision 6\)%, ua
|
|
|
|
assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua
|
|
|
|
ensure
|
|
|
|
util_restore_version
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_user_agent_revision_missing
|
|
|
|
util_save_version
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_PATCHLEVEL
|
|
|
|
Object.send :const_set, :RUBY_PATCHLEVEL, -1
|
|
|
|
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
|
|
|
|
|
2013-09-18 17:29:41 -04:00
|
|
|
ua = Gem::Request.new(@uri, nil, nil, nil).user_agent
|
2013-07-09 19:21:36 -04:00
|
|
|
|
|
|
|
assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua
|
|
|
|
ensure
|
|
|
|
util_restore_version
|
|
|
|
end
|
|
|
|
|
|
|
|
def util_restore_version
|
|
|
|
Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
|
|
|
|
Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if
|
|
|
|
defined?(@orig_RUBY_ENGINE)
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_PATCHLEVEL
|
|
|
|
Object.send :const_set, :RUBY_PATCHLEVEL, @orig_RUBY_PATCHLEVEL
|
|
|
|
|
|
|
|
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
|
|
|
|
Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if
|
|
|
|
defined?(@orig_RUBY_REVISION)
|
|
|
|
end
|
|
|
|
|
|
|
|
def util_save_version
|
|
|
|
@orig_RUBY_ENGINE = RUBY_ENGINE if defined? RUBY_ENGINE
|
|
|
|
@orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL
|
|
|
|
@orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION
|
|
|
|
end
|
|
|
|
|
|
|
|
def util_stub_connection_for hash
|
|
|
|
def @request.connection= conn
|
|
|
|
@conn = conn
|
|
|
|
end
|
|
|
|
|
|
|
|
def @request.connection_for uri
|
|
|
|
@conn
|
|
|
|
end
|
|
|
|
|
|
|
|
@request.connection = Conn.new OpenStruct.new(hash)
|
|
|
|
end
|
|
|
|
|
|
|
|
class Conn
|
|
|
|
attr_accessor :payload
|
|
|
|
|
|
|
|
def initialize(response)
|
|
|
|
@response = response
|
|
|
|
self.payload = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def request(req)
|
|
|
|
self.payload = req
|
|
|
|
@response
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|