From 085e08142d36e8452a48a8ba0f04db1581d61bee Mon Sep 17 00:00:00 2001 From: Bart de Water Date: Wed, 14 Oct 2020 14:43:32 -0400 Subject: [PATCH] Allow setting write_timeout for connections on Ruby 2.6+ (#950) --- README.md | 3 ++- lib/stripe.rb | 1 + lib/stripe/connection_manager.rb | 3 +++ lib/stripe/stripe_configuration.rb | 11 +++++++++++ test/stripe/connection_manager_test.rb | 4 ++++ test/stripe/stripe_configuration_test.rb | 3 +++ test/stripe_test.rb | 13 +++++++++++++ test/test_helper.rb | 2 ++ 8 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 925f81af8..46b2c469f 100644 --- a/README.md +++ b/README.md @@ -186,11 +186,12 @@ retries are safe. ### Configuring Timeouts -Open and read timeouts are configurable: +Open, read and write timeouts are configurable: ```ruby Stripe.open_timeout = 30 # in seconds Stripe.read_timeout = 80 +Stripe.write_timeout = 30 # only supported on Ruby 2.6+ ``` Please take care to set conservative read timeouts. Some API requests can take diff --git a/lib/stripe.rb b/lib/stripe.rb index 13ea28835..fd5dfd5bc 100644 --- a/lib/stripe.rb +++ b/lib/stripe.rb @@ -71,6 +71,7 @@ class << self def_delegators :@configuration, :connect_base, :connect_base= def_delegators :@configuration, :open_timeout, :open_timeout= def_delegators :@configuration, :read_timeout, :read_timeout= + def_delegators :@configuration, :write_timeout, :write_timeout= def_delegators :@configuration, :proxy, :proxy= def_delegators :@configuration, :verify_ssl_certs, :verify_ssl_certs= def_delegators :@configuration, :ca_bundle_path, :ca_bundle_path= diff --git a/lib/stripe/connection_manager.rb b/lib/stripe/connection_manager.rb index af24fb168..e3ecc4bcc 100644 --- a/lib/stripe/connection_manager.rb +++ b/lib/stripe/connection_manager.rb @@ -119,6 +119,9 @@ def execute_request(method, uri, body: nil, headers: nil, query: nil) connection.open_timeout = Stripe.open_timeout connection.read_timeout = Stripe.read_timeout + if connection.respond_to?(:write_timeout=) + connection.write_timeout = Stripe.write_timeout + end connection.use_ssl = uri.scheme == "https" diff --git a/lib/stripe/stripe_configuration.rb b/lib/stripe/stripe_configuration.rb index 71f01f2a4..814d3e650 100644 --- a/lib/stripe/stripe_configuration.rb +++ b/lib/stripe/stripe_configuration.rb @@ -42,6 +42,7 @@ class StripeConfiguration attr_reader :max_network_retry_delay attr_reader :open_timeout attr_reader :read_timeout + attr_reader :write_timeout attr_reader :proxy attr_reader :verify_ssl_certs @@ -72,6 +73,7 @@ def initialize @open_timeout = 30 @read_timeout = 80 + @write_timeout = 30 @api_base = "https://api.stripe.com" @connect_base = "https://connect.stripe.com" @@ -109,6 +111,15 @@ def read_timeout=(read_timeout) StripeClient.clear_all_connection_managers end + def write_timeout=(write_timeout) + unless Net::HTTP.instance_methods.include?(:write_timeout=) + raise NotImplementedError + end + + @write_timeout = write_timeout + StripeClient.clear_all_connection_managers + end + def proxy=(proxy) @proxy = proxy StripeClient.clear_all_connection_managers diff --git a/test/stripe/connection_manager_test.rb b/test/stripe/connection_manager_test.rb index e12a35a24..f73a56eac 100644 --- a/test/stripe/connection_manager_test.rb +++ b/test/stripe/connection_manager_test.rb @@ -39,6 +39,7 @@ class ConnectionManagerTest < Test::Unit::TestCase old_open_timeout = Stripe.open_timeout old_read_timeout = Stripe.read_timeout + old_write_timeout = Stripe.write_timeout begin # Make sure any global initialization here is undone in the `ensure` @@ -47,6 +48,7 @@ class ConnectionManagerTest < Test::Unit::TestCase Stripe.open_timeout = 123 Stripe.read_timeout = 456 + Stripe.write_timeout = 789 if WRITE_TIMEOUT_SUPPORTED conn = @manager.connection_for("https://stripe.com") @@ -63,6 +65,7 @@ class ConnectionManagerTest < Test::Unit::TestCase # Timeouts assert_equal 123, conn.open_timeout assert_equal 456, conn.read_timeout + assert_equal 789, conn.write_timeout if WRITE_TIMEOUT_SUPPORTED assert_equal true, conn.use_ssl? assert_equal OpenSSL::SSL::VERIFY_PEER, conn.verify_mode @@ -72,6 +75,7 @@ class ConnectionManagerTest < Test::Unit::TestCase Stripe.open_timeout = old_open_timeout Stripe.read_timeout = old_read_timeout + Stripe.write_timeout = old_write_timeout if WRITE_TIMEOUT_SUPPORTED end end diff --git a/test/stripe/stripe_configuration_test.rb b/test/stripe/stripe_configuration_test.rb index 774d5ea3f..1630aa3d0 100644 --- a/test/stripe/stripe_configuration_test.rb +++ b/test/stripe/stripe_configuration_test.rb @@ -16,6 +16,7 @@ class StripeConfigurationTest < Test::Unit::TestCase assert_equal 0, config.max_network_retries assert_equal 30, config.open_timeout assert_equal 80, config.read_timeout + assert_equal 30, config.write_timeout assert_equal "https://api.stripe.com", config.api_base assert_equal "https://connect.stripe.com", config.connect_base assert_equal "https://files.stripe.com", config.uploads_base @@ -25,10 +26,12 @@ class StripeConfigurationTest < Test::Unit::TestCase config = Stripe::StripeConfiguration.setup do |c| c.open_timeout = 100 c.read_timeout = 100 + c.write_timeout = 100 if WRITE_TIMEOUT_SUPPORTED end assert_equal 100, config.open_timeout assert_equal 100, config.read_timeout + assert_equal 100, config.write_timeout if WRITE_TIMEOUT_SUPPORTED end end diff --git a/test/stripe_test.rb b/test/stripe_test.rb index 11f100b85..53e9d009f 100644 --- a/test/stripe_test.rb +++ b/test/stripe_test.rb @@ -54,6 +54,19 @@ class StripeTest < Test::Unit::TestCase assert_equal 10, Stripe.read_timeout end + if WRITE_TIMEOUT_SUPPORTED + should "allow write timeout to be configured" do + Stripe.write_timeout = 10 + assert_equal 10, Stripe.write_timeout + end + else + should "raise when write timeout to be configured is not supported" do + assert_raises NotImplementedError do + Stripe.write_timeout = 10 + end + end + end + should "allow api_key to be configured" do Stripe.api_key = "sk_local_test" assert_equal "sk_local_test", Stripe.api_key diff --git a/test/test_helper.rb b/test/test_helper.rb index 319b78c89..1c4299db8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -56,6 +56,8 @@ class TestCase include Stripe::TestData include Mocha + WRITE_TIMEOUT_SUPPORTED = Net::HTTP.instance_methods.include?(:write_timeout=) + setup do Stripe.api_key = "sk_test_123" Stripe.api_base = "http://localhost:#{MOCK_PORT}"