Client -> Session (signal this as deprecation, as this is public API

This commit is contained in:
HoneyryderChuck 2019-03-16 16:32:33 +00:00
parent 05543d12f6
commit c1c0c536eb
17 changed files with 144 additions and 111 deletions

View File

@ -17,7 +17,7 @@ require "httpx/headers"
require "httpx/request"
require "httpx/response"
require "httpx/chainable"
require "httpx/client"
require "httpx/session"
# Top-Level Namespace
#
@ -47,5 +47,11 @@ module HTTPX
end
end
def self.const_missing(const_name)
super unless const_name == :Client
warn "DEPRECATION WARNING: the class #{self}::Client is deprecated. Use #{self}::Session instead."
Session
end
extend Chainable
end

View File

@ -21,7 +21,7 @@ module Faraday
include RequestMixin
class Client < ::HTTPX::Client
class Session < ::HTTPX::Session
plugin(:compression)
module ReasonPlugin
@ -93,7 +93,7 @@ module Faraday
include RequestMixin
def initialize
@client = Client.new
@session = Session.new
@handlers = []
end
@ -119,10 +119,10 @@ module Faraday
proxy_options = { uri: env.request.proxy }
client = @client.with(options)
client = client.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
session = @session.with(options)
session = session.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
responses = client.request(requests)
responses = session.request(requests)
responses.each_with_index do |response, index|
handler = @handlers[index]
handler.on_response.call(response)
@ -141,7 +141,7 @@ module Faraday
def initialize(app)
super(app)
@client = Client.new
@session = Session.new
end
def call(env)
@ -169,9 +169,9 @@ module Faraday
proxy_options = { uri: env.request.proxy }
client = @client.with(options)
client = client.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
response = client.__send__(*request_options)
session = @session.with(options)
session = session.plugin(:proxy).with_proxy(proxy_options) if env.request.proxy
response = session.__send__(*request_options)
response.raise_for_status unless response.is_a?(::HTTPX::Response)
save_response(env, response.status, response.body, response.headers, response.reason) do |response_headers|
response_headers.merge!(response.headers)

View File

@ -29,7 +29,7 @@ module HTTPX
end
def plugin(*plugins)
klass = is_a?(Client) ? self.class : Client
klass = is_a?(Session) ? self.class : Session
klass = Class.new(klass)
klass.instance_variable_set(:@default_options, klass.default_options.merge(default_options))
klass.plugins(plugins).new
@ -48,9 +48,9 @@ module HTTPX
# :nodoc:
def branch(options, &blk)
return self.class.new(options, &blk) if is_a?(Client)
return self.class.new(options, &blk) if is_a?(Session)
Client.new(options, &blk)
Session.new(options, &blk)
end
end
end

View File

@ -57,11 +57,11 @@ module HTTPX
def wrap
return unless block_given?
super do |client|
super do |session|
old_cookies_store = @cookies_store
@cookies_store = old_cookies_store.dup
begin
yield client
yield session
ensure
@cookies_store = old_cookies_store
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module HTTPX
class Client
class Session
include Loggable
include Chainable

View File

@ -6,14 +6,14 @@ require_relative "../test_helper"
class UnixTest < Minitest::Test
include HTTPX
def test_unix_client
def test_unix_session
on_unix_server do |path|
client = Client.new(transport: "unix", transport_options: { path: path })
response = client.get("http://unix.com/ping")
session = Session.new(transport: "unix", transport_options: { path: path })
response = session.get("http://unix.com/ping")
assert response.status == 200, "unexpected code (#{response.status})"
assert response.to_s == "pong", "unexpected body (#{response})"
response.close
client.close
session.close
end
end

View File

@ -2,42 +2,42 @@
require_relative "test_helper"
class ClientTest < Minitest::Test
class SessionTest < Minitest::Test
include HTTPX
def test_client_block
def test_session_block
yielded = nil
Client.new do |cli|
Session.new do |cli|
yielded = cli
end
assert yielded.is_a?(Client), "client should have been yielded"
assert yielded.is_a?(Session), "session should have been yielded"
end
def test_client_plugin
klient_class = Class.new(Client)
def test_session_plugin
klient_class = Class.new(Session)
klient_class.plugin(TestPlugin)
client = klient_class.new
assert client.respond_to?(:foo), "instance methods weren't added"
assert client.foo == "client-foo", "instance method is unexpected"
assert client.respond_to?(:bar), "load and configure didn't work"
assert client.bar == "config-load-bar", "load and configure didn't work"
session = klient_class.new
assert session.respond_to?(:foo), "instance methods weren't added"
assert session.foo == "session-foo", "instance method is unexpected"
assert session.respond_to?(:bar), "load and configure didn't work"
assert session.bar == "config-load-bar", "load and configure didn't work"
assert client.respond_to?(:options), "instance methods weren't added"
assert client.options.respond_to?(:foo), "options methods weren't added"
assert client.options.foo == "options-foo", "option method is unexpected"
assert session.respond_to?(:options), "instance methods weren't added"
assert session.options.respond_to?(:foo), "options methods weren't added"
assert session.options.foo == "options-foo", "option method is unexpected"
request = client.options.request_class.new(:get, "/", client.options)
request = session.options.request_class.new(:get, "/", session.options)
assert request.respond_to?(:foo), "request methods haven't been added"
assert request.foo == "request-foo", "request method is unexpected"
assert request.headers.respond_to?(:foo), "headers methods haven't been added"
assert request.headers.foo == "headers-foo", "headers method is unexpected"
assert client.respond_to?(:response), "response constructor was added"
assert session.respond_to?(:response), "response constructor was added"
req_body = request.body
assert req_body.respond_to?(:foo), "request body methods haven't been added"
assert req_body.foo == "request-body-foo", "request body method is unexpected"
response = client.response(nil, 200, "2.0", {})
response = session.response(nil, 200, "2.0", {})
assert response.respond_to?(:foo), "response methods haven't been added"
assert response.foo == "response-foo", "response method is unexpected"
assert request.headers.respond_to?(:foo), "headers methods haven't been added"
@ -51,7 +51,7 @@ class ClientTest < Minitest::Test
TestPlugin = Module.new do
self::ClassMethods = Module.new do
def foo
"client-foo"
"session-foo"
end
end
self::InstanceMethods = Module.new do

View File

@ -0,0 +1,27 @@
[ req ]
#default_bits = 2048
#default_md = sha256
#default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (eg, fully qualified host name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
[ alt_names ]
DNS.1 = another

View File

@ -8,20 +8,20 @@ module Requests
verify_status(no_auth_response, 401)
verify_header(no_auth_response.headers, "www-authenticate", "Basic realm=\"Fake Realm\"")
client = HTTPX.plugin(:basic_authentication)
response = client.basic_authentication(user, pass).get(basic_auth_uri)
session = HTTPX.plugin(:basic_authentication)
response = session.basic_authentication(user, pass).get(basic_auth_uri)
verify_status(response, 200)
body = json_body(response)
verify_header(body, "authenticated", true)
verify_header(body, "user", user)
invalid_response = client.basic_authentication(user, "fake").get(basic_auth_uri)
invalid_response = session.basic_authentication(user, "fake").get(basic_auth_uri)
verify_status(invalid_response, 401)
end
def test_plugin_digest_authentication
client = HTTPX.plugin(:digest_authentication).headers("cookie" => "fake=fake_value")
response = client.digest_authentication(user, pass).get(digest_auth_uri)
session = HTTPX.plugin(:digest_authentication).headers("cookie" => "fake=fake_value")
response = session.digest_authentication(user, pass).get(digest_auth_uri)
verify_status(response, 200)
body = json_body(response)
verify_header(body, "authenticated", true)

View File

@ -10,26 +10,26 @@ module Requests
verify_status(response1, 200)
assert !response1.headers.key?("content-encoding"), "response should come in plain text"
client = HTTPX.plugin(:compression)
response = client.get(url)
session = HTTPX.plugin(:compression)
response = session.get(url)
skip if response == 429
verify_status(response, 200)
verify_header(response.headers, "content-encoding", "gzip")
end
def test_plugin_compression_gzip
client = HTTPX.plugin(:compression)
session = HTTPX.plugin(:compression)
uri = build_uri("/gzip")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
body = json_body(response)
assert body["gzipped"], "response should be gzipped"
end
def test_plugin_compression_gzip_post
client = HTTPX.plugin(:compression)
session = HTTPX.plugin(:compression)
uri = build_uri("/post")
response = client.headers("content-encoding" => "gzip")
response = session.headers("content-encoding" => "gzip")
.post(uri, body: "a" * 8012)
verify_status(response, 200)
body = json_body(response)
@ -39,18 +39,18 @@ module Requests
end
def test_plugin_compression_deflate
client = HTTPX.plugin(:compression)
session = HTTPX.plugin(:compression)
uri = build_uri("/deflate")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
body = json_body(response)
assert body["deflated"], "response should be deflated"
end
def test_plugin_compression_deflate_post
client = HTTPX.plugin(:compression)
session = HTTPX.plugin(:compression)
uri = build_uri("/post")
response = client.headers("content-encoding" => "deflate")
response = session.headers("content-encoding" => "deflate")
.post(uri, body: "a" * 8012)
verify_status(response, 200)
body = json_body(response)
@ -61,17 +61,17 @@ module Requests
unless RUBY_ENGINE == "jruby"
def test_plugin_compression_brotli
client = HTTPX.plugin(:"compression/brotli")
response = client.get("http://httpbin.org/brotli")
session = HTTPX.plugin(:"compression/brotli")
response = session.get("http://httpbin.org/brotli")
verify_status(response, 200)
body = json_body(response)
assert body["brotli"], "response should be deflated"
end
def test_plugin_compression_brotli_post
client = HTTPX.plugin(:"compression/brotli")
session = HTTPX.plugin(:"compression/brotli")
uri = build_uri("/post")
response = client.headers("content-encoding" => "br")
response = session.headers("content-encoding" => "br")
.post(uri, body: "a" * 8012)
verify_status(response, 200)
body = json_body(response)

View File

@ -4,50 +4,50 @@ module Requests
module Plugins
module Cookies
def test_plugin_cookies_get
client = HTTPX.plugin(:cookies)
response = client.get(cookies_uri)
session = HTTPX.plugin(:cookies)
response = session.get(cookies_uri)
body = json_body(response)
assert body.key?("cookies")
assert body["cookies"].empty?
session_response = client.with_cookies("abc" => "def").get(cookies_uri)
session_response = session.with_cookies("abc" => "def").get(cookies_uri)
body = json_body(session_response)
assert body.key?("cookies")
assert body["cookies"]["abc"] == "def", "abc wasn't properly set"
end
def test_plugin_cookies_set
client = HTTPX.plugin(:cookies)
session = HTTPX.plugin(:cookies)
session_cookies = { "a" => "b", "c" => "d" }
session_uri = cookies_set_uri(session_cookies)
session_response = client.get(session_uri)
session_response = session.get(session_uri)
verify_status(session_response, 302)
verify_cookies(client.cookies_store[URI(session_uri)], session_cookies)
verify_cookies(session.cookies_store[URI(session_uri)], session_cookies)
# first request sets the session
response = client.get(cookies_uri)
response = session.get(cookies_uri)
body = json_body(response)
assert body.key?("cookies")
verify_cookies(body["cookies"], session_cookies)
# second request reuses the session
extra_cookie_response = client.with_cookies("e" => "f").get(cookies_uri)
extra_cookie_response = session.with_cookies("e" => "f").get(cookies_uri)
body = json_body(extra_cookie_response)
assert body.key?("cookies")
verify_cookies(body["cookies"], session_cookies.merge("e" => "f"))
# redirect to a different origin only uses the option cookies
other_origin_response = client.with_cookies("e" => "f").get(redirect_uri(origin("google.com")))
other_origin_response = session.with_cookies("e" => "f").get(redirect_uri(origin("google.com")))
verify_status(other_origin_response, 302)
assert !other_origin_response.headers.key?("set-cookie"), "cookies should not transition to next origin"
end
def test_plugin_cookies_follow
client = HTTPX.plugins(:follow_redirects, :cookies)
session = HTTPX.plugins(:follow_redirects, :cookies)
session_cookies = { "a" => "b", "c" => "d" }
session_uri = cookies_set_uri(session_cookies)
response = client.get(session_uri)
response = session.get(session_uri)
verify_status(response, 200)
assert response.uri.to_s == cookies_uri
body = json_body(response)

View File

@ -8,8 +8,8 @@ module Requests
verify_status(no_redirect_response, 302)
verify_header(no_redirect_response.headers, "location", redirect_location)
client = HTTPX.plugin(:follow_redirects)
redirect_response = client.get(redirect_uri)
session = HTTPX.plugin(:follow_redirects)
redirect_response = session.get(redirect_uri)
verify_status(redirect_response, 200)
body = json_body(redirect_response)
assert body.key?("url"), "url should be set"
@ -17,36 +17,36 @@ module Requests
end
def test_plugin_follow_redirects_default_max_redirects
client = HTTPX.plugin(:follow_redirects)
session = HTTPX.plugin(:follow_redirects)
response = client.get(max_redirect_uri(3))
response = session.get(max_redirect_uri(3))
verify_status(response, 200)
response = client.get(max_redirect_uri(4))
response = session.get(max_redirect_uri(4))
verify_status(response, 302)
end
def test_plugin_follow_redirects_max_redirects
client = HTTPX.plugin(:follow_redirects)
session = HTTPX.plugin(:follow_redirects)
response = client.max_redirects(1).get(max_redirect_uri(1))
response = session.max_redirects(1).get(max_redirect_uri(1))
verify_status(response, 200)
response = client.max_redirects(1).get(max_redirect_uri(2))
response = session.max_redirects(1).get(max_redirect_uri(2))
verify_status(response, 302)
end
def test_plugin_follow_insecure_no_insecure_downgrade
return unless origin.start_with?("https")
client = HTTPX.plugin(:follow_redirects).max_redirects(1)
response = client.get(insecure_redirect_uri)
session = HTTPX.plugin(:follow_redirects).max_redirects(1)
response = session.get(insecure_redirect_uri)
assert response.is_a?(HTTPX::ErrorResponse), "request should not follow insecure URLs"
insecure_client = HTTPX.plugin(:follow_redirects)
insecure_session = HTTPX.plugin(:follow_redirects)
.max_redirects(1)
.with(follow_insecure_redirects: true)
insecure_response = insecure_client.get(insecure_redirect_uri)
insecure_response = insecure_session.get(insecure_redirect_uri)
assert insecure_response.is_a?(HTTPX::Response), "request should follow insecure URLs"
end

View File

@ -11,9 +11,9 @@ module Requests
end
def test_plugin_h2c
client = HTTPX.plugin(:h2c)
session = HTTPX.plugin(:h2c)
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
assert response.version == "2.0", "http h2c requests should be in HTTP/2"
end

View File

@ -6,46 +6,46 @@ module Requests
include ProxyHelper
def test_plugin_http_proxy
client = HTTPX.plugin(:proxy).with_proxy(uri: http_proxy)
session = HTTPX.plugin(:proxy).with_proxy(uri: http_proxy)
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
end
def test_plugin_socks4_proxy
client = HTTPX.plugin(:proxy).with_proxy(uri: socks4_proxy)
session = HTTPX.plugin(:proxy).with_proxy(uri: socks4_proxy)
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
end
def test_plugin_socks4a_proxy
client = HTTPX.plugin(:proxy).with_proxy(uri: socks4a_proxy)
session = HTTPX.plugin(:proxy).with_proxy(uri: socks4a_proxy)
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
end
def test_plugin_socks5_proxy
client = HTTPX.plugin(:proxy).with_proxy(uri: socks5_proxy)
session = HTTPX.plugin(:proxy).with_proxy(uri: socks5_proxy)
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
end
def test_plugin_ssh_proxy
skip if RUBY_ENGINE == "jruby"
client = HTTPX.plugin(:"proxy/ssh").with_proxy(uri: ssh_proxy,
session = HTTPX.plugin(:"proxy/ssh").with_proxy(uri: ssh_proxy,
username: "root",
auth_methods: %w[publickey],
host_key: "ssh-rsa",
keys: %w[test/support/ssh/ssh_host_ed25519_key])
uri = build_uri("/get")
response = client.get(uri)
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
end if ENV.key?("HTTPX_SSH_PROXY")

View File

@ -4,17 +4,17 @@ module Requests
module Plugins
module PushPromise
def test_plugin_push_promise_get
client = HTTPX.plugin(:push_promise)
html, css = client.get(push_html_uri, push_css_uri)
session = HTTPX.plugin(:push_promise)
html, css = session.get(push_html_uri, push_css_uri)
verify_status(html, 200)
verify_status(css, 200)
verify_header(css.headers, "x-http2-push", "1")
end
def test_plugin_push_promise_concurrent
client = HTTPX.plugin(:push_promise)
session = HTTPX.plugin(:push_promise)
.with(max_concurrent_requests: 100)
html, css = client.get(push_html_uri, push_css_uri)
html, css = session.get(push_html_uri, push_css_uri)
verify_status(html, 200)
verify_status(css, 200)
verify_no_header(css.headers, "x-http2-push")

View File

@ -4,32 +4,32 @@ module Requests
module Plugins
module Retries
def test_plugin_retries
no_retries_client = HTTPX.plugin(RequestInspector).timeout(total_timeout: 3)
no_retries_response = no_retries_client.get(build_uri("/delay/10"))
no_retries_session = HTTPX.plugin(RequestInspector).timeout(total_timeout: 3)
no_retries_response = no_retries_session.get(build_uri("/delay/10"))
assert no_retries_response.is_a?(HTTPX::ErrorResponse)
assert no_retries_client.calls == 1, "expect request to be built 1 times (was #{no_retries_client.calls})"
retries_client = HTTPX
assert no_retries_session.calls == 1, "expect request to be built 1 times (was #{no_retries_session.calls})"
retries_session = HTTPX
.plugin(RequestInspector)
.plugin(:retries)
.timeout(total_timeout: 3)
retries_response = retries_client.get(build_uri("/delay/10"))
retries_response = retries_session.get(build_uri("/delay/10"))
assert retries_response.is_a?(HTTPX::ErrorResponse)
# we're comparing against max-retries + 1, because the calls increment will happen
# also in the last call, where the request is not going to be retried.
assert retries_client.calls == 4, "expect request to be built 4 times (was #{retries_client.calls})"
assert retries_session.calls == 4, "expect request to be built 4 times (was #{retries_session.calls})"
end
def test_plugin_retries_max_retries
retries_client = HTTPX
retries_session = HTTPX
.plugin(RequestInspector)
.plugin(:retries)
.timeout(total_timeout: 3)
.max_retries(2)
retries_response = retries_client.get(build_uri("/delay/10"))
retries_response = retries_session.get(build_uri("/delay/10"))
assert retries_response.is_a?(HTTPX::ErrorResponse)
# we're comparing against max-retries + 1, because the calls increment will happen
# also in the last call, where the request is not going to be retried.
assert retries_client.calls == 3, "expect request to be built 3 times (was #{retries_client.calls})"
assert retries_session.calls == 3, "expect request to be built 3 times (was #{retries_session.calls})"
end
module RequestInspector

View File

@ -4,24 +4,24 @@ module Requests
module Timeouts
# def test_http_timeouts_operation_timeout
# uri = build_uri("/delay/2")
# client = HTTPX.timeout(operation_timeout: 1)
# response = client.get(uri)
# session = HTTPX.timeout(operation_timeout: 1)
# response = session.get(uri)
# assert response.is_a?(HTTPX::ErrorResponse), "response should have failed"
# assert response.error =~ /timed out while waiting/, "response should have timed out"
# end
def test_http_timeouts_total_timeout
uri = build_uri("/delay/3")
client = HTTPX.timeout(operation_timeout: 1, total_timeout: 2)
response = client.get(uri)
session = HTTPX.timeout(operation_timeout: 1, total_timeout: 2)
response = session.get(uri)
assert response.is_a?(HTTPX::ErrorResponse), "response should have failed"
assert response.status =~ /timed out after 2 seconds/i, "response should have timed out"
end
# def test_http_timeout_connect_timeout
# uri = build_uri("/delay/3")
# client = HTTPX.timeout(connect_timeout: 0.5, operation_timeout: 30, total_timeout: 2)
# response = client.get(uri)
# session = HTTPX.timeout(connect_timeout: 0.5, operation_timeout: 30, total_timeout: 2)
# response = session.get(uri)
# assert response.is_a?(HTTPX::ErrorResponse), "response should have failed"
# assert response.error.is_a?(HTTPX::ConnectTimeoutError), "response should have failed on connection"
# end