introducing the :no_proxy option

can be passed in the `:proxy` option hash, and receives domains, as
strings, which requests should not go through the proxy.
This commit is contained in:
HoneyryderChuck 2022-08-04 22:42:57 +01:00
parent 39beff84ab
commit 43016795f3
7 changed files with 42 additions and 10 deletions

View File

@ -18,7 +18,11 @@ group :test do
gem "ruby-ntlm"
gem "sentry-ruby" if RUBY_VERSION >= "2.4"
gem "spy"
gem "webmock"
if RUBY_VERSION < "2.3.0"
gem "webmock", "< 3.15.0"
else
gem "webmock"
end
gem "websocket-driver"
gem "net-ssh", "~> 4.2.0" if RUBY_VERSION < "2.2"
@ -115,8 +119,8 @@ group :assorted do
if RUBY_VERSION < "2.2"
gem "pry-byebug", "~> 3.4.3"
else
gem "pry-byebug"
gem "debug" if RUBY_VERSION >= "3.1.0"
gem "pry-byebug"
end
end
end

View File

@ -3,6 +3,7 @@ services:
httpx:
environment:
- HTTPBIN_HOST=nghttp2
- HTTPBIN_NO_PROXY_HOST=http://httpbin:8000
- HTTPX_HTTP_PROXY=http://proxyuser:password@httpproxy:3128
- HTTPX_HTTPS_PROXY=http://proxyuser:password@httpproxy:3128
- HTTPX_HTTP2_PROXY=http://proxyuser:password@http2proxy:80

View File

@ -105,6 +105,10 @@ module HTTPX
end
return if @_proxy_uris.empty?
proxy = options.proxy
return { uri: uri.host } if proxy && proxy.key?(:no_proxy) && !Array(proxy[:no_proxy]).grep(uri.host).empty?
proxy_opts = { uri: @_proxy_uris.first }
proxy_opts = options.proxy.merge(proxy_opts) if options.proxy
proxy_opts
@ -117,7 +121,9 @@ module HTTPX
next_proxy = proxy_uris(uri, options)
raise Error, "Failed to connect to proxy" unless next_proxy
proxy_options = options.merge(proxy: Parameters.new(**next_proxy))
proxy = Parameters.new(**next_proxy) unless next_proxy[:uri] == uri.host
proxy_options = options.merge(proxy: proxy)
connection = pool.find_connection(uri, proxy_options) || build_connection(uri, proxy_options)
unless connections.nil? || connections.include?(connection)
connections << connection

View File

@ -21,7 +21,7 @@ module HTTPX
private
def initialize: (uri: generic_uri, ?scheme: String, ?username: String, ?password: String, **extra) -> untyped
def initialize: (uri: generic_uri, ?scheme: String, ?username: String, ?password: String, **untyped) -> untyped
end
def self.configure: (singleton(Session)) -> void

View File

@ -21,4 +21,8 @@ module HTTPHelpers
def httpbin
ENV.fetch("HTTPBIN_HOST", "nghttp2.org/httpbin")
end
def httpbin_no_proxy
URI(ENV.fetch("HTTPBIN_NO_PROXY_HOST", "httpbin.org"))
end
end

View File

@ -17,7 +17,7 @@ module ProxyResponseDetector
module ConnectionMethods
def send(request)
return super unless @options.respond_to?(:proxy)
return super unless @options.respond_to?(:proxy) && @options.proxy
proxy_uri = URI(@options.proxy.uri)

View File

@ -16,7 +16,7 @@ module Requests
assert_raises(HTTPX::HTTPProxyError) { session.get(uri) }
end
def test_plugin_http_http1_proxy
def test_plugin_http_http_proxy
return unless origin.start_with?("http://")
session = HTTPX.plugin(:proxy, fallback_protocol: "http/1.1").plugin(ProxyResponseDetector).with_proxy(uri: http_proxy)
@ -27,6 +27,26 @@ module Requests
assert response.proxied?
end
def test_plugin_http_no_proxy
return unless origin.start_with?("http://")
session = HTTPX.plugin(:proxy).plugin(ProxyResponseDetector).with_proxy(uri: http_proxy, no_proxy: [httpbin_no_proxy.host])
# proxy
uri = build_uri("/get")
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
assert response.proxied?
# no proxy
no_proxy_uri = build_uri("/get", httpbin_no_proxy)
no_proxy_response = session.get(no_proxy_uri)
verify_status(no_proxy_response, 200)
verify_body_length(no_proxy_response)
assert !no_proxy_response.proxied?
end
def test_plugin_http_h2_proxy
return unless origin.start_with?("http://")
@ -99,11 +119,10 @@ module Requests
no_auth_proxy.user = nil
no_auth_proxy.password = nil
session = HTTPX.plugin(:proxy).plugin(ProxyResponseDetector).with_proxy(uri: no_auth_proxy.to_s)
session = HTTPX.plugin(:proxy).with_proxy(uri: no_auth_proxy.to_s)
uri = build_uri("/get")
response = session.get(uri)
verify_status(response, 407)
assert response.proxied?
end
def test_plugin_http_proxy_digest_auth
@ -228,7 +247,6 @@ module Requests
def test_plugin_ssh_proxy
session = HTTPX.plugin(:"proxy/ssh")
.plugin(ProxyResponseDetector)
.with_proxy(uri: ssh_proxy,
username: "root",
auth_methods: %w[publickey],
@ -238,7 +256,6 @@ module Requests
response = session.get(uri)
verify_status(response, 200)
verify_body_length(response)
assert response.proxied?
end if ENV.key?("HTTPX_SSH_PROXY") && RUBY_ENGINE != "jruby"
end
end