httpx/test/https_test.rb
2021-01-31 15:51:34 +00:00

125 lines
4.5 KiB
Ruby

# frozen_string_literal: true
require_relative "support/http_helpers"
class HTTPSTest < Minitest::Test
include HTTPHelpers
include Requests
include Get
include Head
include WithBody
include Headers
include ResponseBody
include IO
include Errors
include Resolvers if ENV.key?("HTTPX_RESOLVER_URI")
# TODO: uncomment as soon as nghttpx supports altsvc for HTTP/2
# include AltSvc if ENV.key?("HTTPBIN_ALTSVC_HOST")
include Plugins::Proxy unless ENV.key?("HTTPX_NO_PROXY")
include Plugins::Authentication
include Plugins::FollowRedirects
include Plugins::Cookies
include Plugins::Compression
include Plugins::PushPromise if OpenSSL::SSL::SSLContext.instance_methods.include?(:alpn_protocols)
include Plugins::Retries
include Plugins::Multipart
include Plugins::Expect
include Plugins::RateLimiter
include Plugins::Persistent unless RUBY_ENGINE == "jruby" || RUBY_VERSION < "2.3"
include Plugins::Stream
def test_connection_coalescing
coalesced_origin = "https://#{ENV["HTTPBIN_COALESCING_HOST"]}"
HTTPX.plugin(SessionWithPool).wrap do |http|
response1 = http.get(origin)
verify_status(response1, 200)
response2 = http.get(coalesced_origin)
verify_status(response2, 200)
# introspection time
pool = http.pool
connections = pool.connections
origins = connections.map(&:origins)
assert origins.any? { |orgs| orgs.sort == [origin, coalesced_origin].sort },
"connections for #{[origin, coalesced_origin]} didn't coalesce (expected connection with both origins (#{origins}))"
end
end if ENV.key?("HTTPBIN_COALESCING_HOST")
def test_verbose_log
log = StringIO.new
uri = build_uri("/get")
response = HTTPX.get(uri, debug: log, debug_level: 2)
verify_status(response, 200)
log_output = log.string
# assert tls output
assert log_output.match(%r{SSL connection using TLSv\d+\.\d+ / \w+})
assert log_output.match(/ALPN, server accepted to use h2/) unless RUBY_ENGINE == "jruby" || RUBY_VERSION < "2.3"
assert log_output.match(/Server certificate:/)
assert log_output.match(/ subject: .+/)
assert log_output.match(/ start date: .+ UTC/)
assert log_output.match(/ expire date: .+ UTC/)
assert log_output.match(/ issuer: .+/)
assert log_output.match(/ SSL certificate verify ok./)
return if RUBY_ENGINE == "jruby" || RUBY_VERSION < "2.3"
# assert request headers
assert log_output.match(/HEADER: :scheme: https/)
assert log_output.match(/HEADER: :method: GET/)
assert log_output.match(/HEADER: :path: .+/)
assert log_output.match(/HEADER: :authority: .+/)
assert log_output.match(%r{HEADER: accept: */*})
# assert response headers
assert log_output.match(/HEADER: :status: 200/)
assert log_output.match(/HEADER: content-type: \w+/)
assert log_output.match(/HEADER: content-length: \d+/)
end
unless RUBY_ENGINE == "jruby" || RUBY_VERSION < "2.3"
# HTTP/2-specific tests
def test_http2_max_streams
uri = build_uri("/get")
HTTPX.plugin(SessionWithSingleStream).plugin(SessionWithPool).wrap do |http|
http.get(uri, uri)
connection_count = http.pool.connection_count
assert connection_count == 2, "expected to have 2 connections, instead have #{connection_count}"
assert http.connection_exausted, "expected 1 connnection to have exhausted"
end
end
def test_http2_uncoalesce_on_misdirected
uri = build_uri("/status/421")
HTTPX.plugin(SessionWithPool).wrap do |http|
response = http.get(uri)
verify_status(response, 421)
connection_count = http.pool.connection_count
assert connection_count == 2, "expected to have 2 connections, instead have #{connection_count}"
assert response.version == "1.1", "request should have been retried with HTTP/1.1"
end
end
def test_http2_settings_timeout
uri = build_uri("/get")
HTTPX.plugin(SessionWithPool).plugin(SessionWithFrameDelay).wrap do |http|
response = http.get(uri)
verify_error_response(response, /settings_timeout/)
end
end
end
def test_ssl_wrong_hostname
uri = build_uri("/get")
response = HTTPX.with(ssl: { hostname: "great-gatsby.com" }).get(uri)
assert response.is_a?(HTTPX::ErrorResponse), "response should contain errors"
assert response.error.message.include?("certificate verify failed"),
"unexpected error: #{response.error.message}"
end
private
def origin(orig = httpbin)
"https://#{orig}"
end
end