fix: do not subclass session class to make it play along with default

class overrides

the faraday adapter was relying on subclassing the session to load
custom plugins. this doesn't play well with other integrations
monkeypatching the original session class, such as datadog or webmock,
which redefine it. from now on, we not only defer the creation of the
custom until necessary, we also use Session#plugin

Fixes #187
This commit is contained in:
HoneyryderChuck 2022-04-04 12:54:33 +01:00
parent 603fc0979a
commit 1cf8c68ac6
2 changed files with 56 additions and 25 deletions

View File

@ -99,33 +99,31 @@ module Faraday
end end
end end
class Session < ::HTTPX::Session module ReasonPlugin
plugin(:compression) if RUBY_VERSION < "2.5"
plugin(:persistent) def self.load_dependencies(*)
require "webrick"
module ReasonPlugin end
else
def self.load_dependencies(*)
require "net/http/status"
end
end
module ResponseMethods
if RUBY_VERSION < "2.5" if RUBY_VERSION < "2.5"
def self.load_dependencies(*) def reason
require "webrick" WEBrick::HTTPStatus::StatusMessage.fetch(@status)
end end
else else
def self.load_dependencies(*) def reason
require "net/http/status" Net::HTTP::STATUS_CODES.fetch(@status)
end
end
module ResponseMethods
if RUBY_VERSION < "2.5"
def reason
WEBrick::HTTPStatus::StatusMessage.fetch(@status)
end
else
def reason
Net::HTTP::STATUS_CODES.fetch(@status)
end
end end
end end
end end
plugin(ReasonPlugin) end
def self.session
@session ||= ::HTTPX.plugin(:compression).plugin(:persistent).plugin(ReasonPlugin)
end end
class ParallelManager class ParallelManager
@ -161,7 +159,6 @@ module Faraday
include RequestMixin include RequestMixin
def initialize def initialize
@session = Session.new
@handlers = [] @handlers = []
end end
@ -174,7 +171,7 @@ module Faraday
def run def run
env = @handlers.last.env env = @handlers.last.env
session = @session.with(options_from_env(env)) session = HTTPX.session.with(options_from_env(env))
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
session = session.plugin(OnDataPlugin) if env.request.stream_response? session = session.plugin(OnDataPlugin) if env.request.stream_response?
@ -205,7 +202,7 @@ module Faraday
def initialize(app, options = {}) def initialize(app, options = {})
super(app) super(app)
@session = Session.new(options) @session_options = options
end end
def call(env) def call(env)
@ -221,7 +218,9 @@ module Faraday
return handler return handler
end end
session = @session.with(options_from_env(env)) session = HTTPX.session
session = session.with(@session_options) unless @session_options.empty?
session = session.with(options_from_env(env))
session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy session = session.plugin(:proxy).with(proxy: { uri: env.request.proxy }) if env.request.proxy
session = session.plugin(OnDataPlugin) if env.request.stream_response? session = session.plugin(OnDataPlugin) if env.request.stream_response?

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
require "test_helper"
require "support/http_helpers"
require "support/minitest_extensions"
require "httpx/adapters/faraday"
require "webmock/minitest"
require "httpx/adapters/webmock"
class FaradayWithWebmockTest < Minitest::Test
include HTTPHelpers
def setup
super
WebMock.enable!
WebMock.disable_net_connect!
end
def teardown
super
WebMock.reset!
WebMock.allow_net_connect!
WebMock.disable!
end
def test_0_19_5_bug_faraday_and_webmock_dont_play_along
stub_http_request(:any, "https://www.smthfishy.com").to_return(status: 200)
faraday = Faraday.new { |builder| builder.adapter :httpx }
response = faraday.get("https://www.smthfishy.com/")
assert response.status == 200
end
end