stripe 5.30.0 → 5.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/Gemfile +0 -1
- data/README.md +0 -1
- data/VERSION +1 -1
- data/lib/stripe.rb +23 -21
- data/lib/stripe/connection_manager.rb +10 -8
- data/lib/stripe/oauth.rb +4 -3
- data/lib/stripe/object_types.rb +2 -0
- data/lib/stripe/resources.rb +2 -0
- data/lib/stripe/resources/account.rb +3 -8
- data/lib/stripe/resources/file.rb +2 -1
- data/lib/stripe/resources/identity/verification_report.rb +12 -0
- data/lib/stripe/resources/identity/verification_session.rb +35 -0
- data/lib/stripe/stripe_client.rb +131 -64
- data/lib/stripe/stripe_configuration.rb +25 -9
- data/lib/stripe/stripe_object.rb +23 -0
- data/lib/stripe/util.rb +12 -6
- data/lib/stripe/version.rb +1 -1
- data/stripe.gemspec +9 -2
- metadata +5 -194
- data/.editorconfig +0 -10
- data/.gitattributes +0 -4
- data/.github/ISSUE_TEMPLATE.md +0 -5
- data/.gitignore +0 -8
- data/.rubocop.yml +0 -81
- data/.rubocop_todo.yml +0 -33
- data/.travis.yml +0 -38
- data/.vscode/extensions.json +0 -7
- data/.vscode/settings.json +0 -8
- data/test/openapi/README.md +0 -9
- data/test/stripe/account_link_test.rb +0 -18
- data/test/stripe/account_test.rb +0 -412
- data/test/stripe/alipay_account_test.rb +0 -37
- data/test/stripe/api_operations_test.rb +0 -80
- data/test/stripe/api_resource_test.rb +0 -646
- data/test/stripe/apple_pay_domain_test.rb +0 -46
- data/test/stripe/application_fee_refund_test.rb +0 -37
- data/test/stripe/application_fee_test.rb +0 -58
- data/test/stripe/balance_test.rb +0 -13
- data/test/stripe/balance_transaction_test.rb +0 -20
- data/test/stripe/bank_account_test.rb +0 -36
- data/test/stripe/billing_portal/configuration_test.rb +0 -37
- data/test/stripe/billing_portal/session_test.rb +0 -18
- data/test/stripe/capability_test.rb +0 -45
- data/test/stripe/charge_test.rb +0 -64
- data/test/stripe/checkout/session_test.rb +0 -53
- data/test/stripe/connection_manager_test.rb +0 -167
- data/test/stripe/country_spec_test.rb +0 -20
- data/test/stripe/coupon_test.rb +0 -61
- data/test/stripe/credit_note_test.rb +0 -90
- data/test/stripe/customer_balance_transaction_test.rb +0 -37
- data/test/stripe/customer_card_test.rb +0 -48
- data/test/stripe/customer_test.rb +0 -226
- data/test/stripe/dispute_test.rb +0 -51
- data/test/stripe/ephemeral_key_test.rb +0 -93
- data/test/stripe/errors_test.rb +0 -53
- data/test/stripe/exchange_rate_test.rb +0 -20
- data/test/stripe/file_link_test.rb +0 -41
- data/test/stripe/file_test.rb +0 -87
- data/test/stripe/instrumentation_test.rb +0 -74
- data/test/stripe/invoice_item_test.rb +0 -66
- data/test/stripe/invoice_line_item_test.rb +0 -8
- data/test/stripe/invoice_test.rb +0 -229
- data/test/stripe/issuing/authorization_test.rb +0 -72
- data/test/stripe/issuing/card_test.rb +0 -74
- data/test/stripe/issuing/cardholder_test.rb +0 -53
- data/test/stripe/issuing/dispute_test.rb +0 -54
- data/test/stripe/issuing/transaction_test.rb +0 -48
- data/test/stripe/list_object_test.rb +0 -202
- data/test/stripe/login_link_test.rb +0 -37
- data/test/stripe/mandate_test.rb +0 -14
- data/test/stripe/multipart_encoder_test.rb +0 -130
- data/test/stripe/oauth_test.rb +0 -104
- data/test/stripe/order_return_test.rb +0 -21
- data/test/stripe/order_test.rb +0 -82
- data/test/stripe/payment_intent_test.rb +0 -107
- data/test/stripe/payment_method_test.rb +0 -84
- data/test/stripe/payout_test.rb +0 -72
- data/test/stripe/person_test.rb +0 -46
- data/test/stripe/plan_test.rb +0 -98
- data/test/stripe/price_test.rb +0 -48
- data/test/stripe/product_test.rb +0 -58
- data/test/stripe/promotion_code_test.rb +0 -42
- data/test/stripe/radar/early_fraud_warning_test.rb +0 -22
- data/test/stripe/radar/value_list_item_test.rb +0 -48
- data/test/stripe/radar/value_list_test.rb +0 -61
- data/test/stripe/recipient_test.rb +0 -62
- data/test/stripe/refund_test.rb +0 -39
- data/test/stripe/reporting/report_run_test.rb +0 -33
- data/test/stripe/reporting/report_type_test.rb +0 -22
- data/test/stripe/reversal_test.rb +0 -43
- data/test/stripe/review_test.rb +0 -27
- data/test/stripe/setup_attempt_test.rb +0 -16
- data/test/stripe/setup_intent_test.rb +0 -84
- data/test/stripe/sigma/scheduled_query_run_test.rb +0 -22
- data/test/stripe/sku_test.rb +0 -60
- data/test/stripe/source_test.rb +0 -119
- data/test/stripe/stripe_client_test.rb +0 -1291
- data/test/stripe/stripe_configuration_test.rb +0 -131
- data/test/stripe/stripe_object_test.rb +0 -500
- data/test/stripe/stripe_response_test.rb +0 -95
- data/test/stripe/subscription_item_test.rb +0 -84
- data/test/stripe/subscription_schedule_test.rb +0 -82
- data/test/stripe/subscription_test.rb +0 -80
- data/test/stripe/tax_id_test.rb +0 -31
- data/test/stripe/tax_rate_test.rb +0 -43
- data/test/stripe/terminal/connection_token_test.rb +0 -16
- data/test/stripe/terminal/location_test.rb +0 -68
- data/test/stripe/terminal/reader_test.rb +0 -62
- data/test/stripe/three_d_secure_test.rb +0 -23
- data/test/stripe/topup_test.rb +0 -62
- data/test/stripe/transfer_test.rb +0 -88
- data/test/stripe/usage_record_summary_test.rb +0 -29
- data/test/stripe/util_test.rb +0 -402
- data/test/stripe/webhook_endpoint_test.rb +0 -59
- data/test/stripe/webhook_test.rb +0 -135
- data/test/stripe_mock.rb +0 -78
- data/test/stripe_test.rb +0 -132
- data/test/test_data.rb +0 -61
- data/test/test_helper.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bc72681f7c824d84325e741042d894fdc4e1cd643f7f991093632d0c209c2d9
|
4
|
+
data.tar.gz: acc3cc72ea8198b17e0f9863ddd92101d38997427fa3ceda29c487ccfb0ab2c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9e7441d87f5be510eb5bd3a6c814074b9a23819343a37958e94c7a477ef8bac66ca164fa47fa84c3ece5baaa19afd18abbaecc94fb354453b00c0ad9e430d24
|
7
|
+
data.tar.gz: e606a7a81ee1cf74a6e804ad98332c91ee14c8675a8b65b4632e237097c886aa8ca879c1ff1091a47f790fd927f33cc2e73497caea7934d15d8e65ec4fd3a1a1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 5.33.0 - 2021-05-19
|
4
|
+
* [#979](https://github.com/stripe/stripe-ruby/pull/979) API Updates
|
5
|
+
* [#975](https://github.com/stripe/stripe-ruby/pull/975) Add Truffleruby head to CI
|
6
|
+
|
7
|
+
## 5.32.1 - 2021-04-05
|
8
|
+
* Correct use of regexp `match` in gemspec for old versions of Ruby
|
9
|
+
|
10
|
+
## 5.32.0 - 2021-04-05
|
11
|
+
* [#973](https://github.com/stripe/stripe-ruby/pull/973) Reduce packed gem size
|
12
|
+
|
13
|
+
## 5.31.0 - 2021-04-02
|
14
|
+
* [#968](https://github.com/stripe/stripe-ruby/pull/968) Allow StripeClient to be configured per instance
|
15
|
+
* [#971](https://github.com/stripe/stripe-ruby/pull/971) On config change, only clear connection managers for changed config
|
16
|
+
* [#972](https://github.com/stripe/stripe-ruby/pull/972) Rename `Stripe.configuration` to `Stripe.config`
|
17
|
+
* [#970](https://github.com/stripe/stripe-ruby/pull/970) Reserve some critical field names when adding `StripeObject` accessors
|
18
|
+
* [#967](https://github.com/stripe/stripe-ruby/pull/967) CI: github actions
|
19
|
+
|
3
20
|
## 5.30.0 - 2021-02-22
|
4
21
|
* [#965](https://github.com/stripe/stripe-ruby/pull/965) Add support for the Billing Portal Configuration API
|
5
22
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/stripe.svg)](https://badge.fury.io/rb/stripe)
|
4
4
|
[![Build Status](https://travis-ci.org/stripe/stripe-ruby.svg?branch=master)](https://travis-ci.org/stripe/stripe-ruby)
|
5
|
-
[![Coverage Status](https://coveralls.io/repos/github/stripe/stripe-ruby/badge.svg?branch=master)](https://coveralls.io/github/stripe/stripe-ruby?branch=master)
|
6
5
|
|
7
6
|
The Stripe Ruby library provides convenient access to the Stripe API from
|
8
7
|
applications written in the Ruby language. It includes a pre-defined set of
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
5.
|
1
|
+
5.33.0
|
data/lib/stripe.rb
CHANGED
@@ -57,34 +57,36 @@ module Stripe
|
|
57
57
|
|
58
58
|
@app_info = nil
|
59
59
|
|
60
|
-
@
|
60
|
+
@config = Stripe::StripeConfiguration.setup
|
61
61
|
|
62
62
|
class << self
|
63
63
|
extend Forwardable
|
64
64
|
|
65
|
+
attr_reader :config
|
66
|
+
|
65
67
|
# User configurable options
|
66
|
-
def_delegators :@
|
67
|
-
def_delegators :@
|
68
|
-
def_delegators :@
|
69
|
-
def_delegators :@
|
70
|
-
def_delegators :@
|
71
|
-
def_delegators :@
|
72
|
-
def_delegators :@
|
73
|
-
def_delegators :@
|
74
|
-
def_delegators :@
|
75
|
-
def_delegators :@
|
76
|
-
def_delegators :@
|
77
|
-
def_delegators :@
|
78
|
-
def_delegators :@
|
79
|
-
def_delegators :@
|
80
|
-
def_delegators :@
|
81
|
-
def_delegators :@
|
82
|
-
def_delegators :@
|
68
|
+
def_delegators :@config, :api_key, :api_key=
|
69
|
+
def_delegators :@config, :api_version, :api_version=
|
70
|
+
def_delegators :@config, :stripe_account, :stripe_account=
|
71
|
+
def_delegators :@config, :api_base, :api_base=
|
72
|
+
def_delegators :@config, :uploads_base, :uploads_base=
|
73
|
+
def_delegators :@config, :connect_base, :connect_base=
|
74
|
+
def_delegators :@config, :open_timeout, :open_timeout=
|
75
|
+
def_delegators :@config, :read_timeout, :read_timeout=
|
76
|
+
def_delegators :@config, :write_timeout, :write_timeout=
|
77
|
+
def_delegators :@config, :proxy, :proxy=
|
78
|
+
def_delegators :@config, :verify_ssl_certs, :verify_ssl_certs=
|
79
|
+
def_delegators :@config, :ca_bundle_path, :ca_bundle_path=
|
80
|
+
def_delegators :@config, :log_level, :log_level=
|
81
|
+
def_delegators :@config, :logger, :logger=
|
82
|
+
def_delegators :@config, :max_network_retries, :max_network_retries=
|
83
|
+
def_delegators :@config, :enable_telemetry=, :enable_telemetry?
|
84
|
+
def_delegators :@config, :client_id=, :client_id
|
83
85
|
|
84
86
|
# Internal configurations
|
85
|
-
def_delegators :@
|
86
|
-
def_delegators :@
|
87
|
-
def_delegators :@
|
87
|
+
def_delegators :@config, :max_network_retry_delay
|
88
|
+
def_delegators :@config, :initial_network_retry_delay
|
89
|
+
def_delegators :@config, :ca_store
|
88
90
|
end
|
89
91
|
|
90
92
|
# Gets the application for a plugin that's identified some. See
|
@@ -15,8 +15,10 @@ module Stripe
|
|
15
15
|
# by `StripeClient` to determine whether a connection manager should be
|
16
16
|
# garbage collected or not.
|
17
17
|
attr_reader :last_used
|
18
|
+
attr_reader :config
|
18
19
|
|
19
|
-
def initialize
|
20
|
+
def initialize(config = Stripe.config)
|
21
|
+
@config = config
|
20
22
|
@active_connections = {}
|
21
23
|
@last_used = Util.monotonic_time
|
22
24
|
|
@@ -117,17 +119,17 @@ module Stripe
|
|
117
119
|
# reused Go's default for `DefaultTransport`.
|
118
120
|
connection.keep_alive_timeout = 30
|
119
121
|
|
120
|
-
connection.open_timeout =
|
121
|
-
connection.read_timeout =
|
122
|
+
connection.open_timeout = config.open_timeout
|
123
|
+
connection.read_timeout = config.read_timeout
|
122
124
|
if connection.respond_to?(:write_timeout=)
|
123
|
-
connection.write_timeout =
|
125
|
+
connection.write_timeout = config.write_timeout
|
124
126
|
end
|
125
127
|
|
126
128
|
connection.use_ssl = uri.scheme == "https"
|
127
129
|
|
128
|
-
if
|
130
|
+
if config.verify_ssl_certs
|
129
131
|
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
130
|
-
connection.cert_store =
|
132
|
+
connection.cert_store = config.ca_store
|
131
133
|
else
|
132
134
|
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
133
135
|
warn_ssl_verify_none
|
@@ -141,10 +143,10 @@ module Stripe
|
|
141
143
|
# out those pieces to make passing them into a new connection a little less
|
142
144
|
# ugly.
|
143
145
|
private def proxy_parts
|
144
|
-
if
|
146
|
+
if config.proxy.nil?
|
145
147
|
[nil, nil, nil, nil]
|
146
148
|
else
|
147
|
-
u = URI.parse(
|
149
|
+
u = URI.parse(config.proxy)
|
148
150
|
[u.host, u.port, u.user, u.password]
|
149
151
|
end
|
150
152
|
end
|
data/lib/stripe/oauth.rb
CHANGED
@@ -7,8 +7,8 @@ module Stripe
|
|
7
7
|
|
8
8
|
def self.execute_resource_request(method, url, params, opts)
|
9
9
|
opts = Util.normalize_opts(opts)
|
10
|
-
opts[:client] ||= StripeClient.active_client
|
11
|
-
opts[:api_base] ||=
|
10
|
+
opts[:client] ||= opts[:client] || StripeClient.active_client
|
11
|
+
opts[:api_base] ||= opts[:client].config.connect_base
|
12
12
|
|
13
13
|
super(method, url, params, opts)
|
14
14
|
end
|
@@ -29,7 +29,8 @@ module Stripe
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.authorize_url(params = {}, opts = {})
|
32
|
-
|
32
|
+
client = opts[:client] || StripeClient.active_client
|
33
|
+
base = opts[:connect_base] || client.config.connect_base
|
33
34
|
|
34
35
|
path = "/oauth/authorize"
|
35
36
|
path = "/express" + path if opts[:express]
|
data/lib/stripe/object_types.rb
CHANGED
@@ -41,6 +41,8 @@ module Stripe
|
|
41
41
|
File::OBJECT_NAME => File,
|
42
42
|
File::OBJECT_NAME_ALT => File,
|
43
43
|
FileLink::OBJECT_NAME => FileLink,
|
44
|
+
Identity::VerificationReport::OBJECT_NAME => Identity::VerificationReport,
|
45
|
+
Identity::VerificationSession::OBJECT_NAME => Identity::VerificationSession,
|
44
46
|
Invoice::OBJECT_NAME => Invoice,
|
45
47
|
InvoiceItem::OBJECT_NAME => InvoiceItem,
|
46
48
|
InvoiceLineItem::OBJECT_NAME => InvoiceLineItem,
|
data/lib/stripe/resources.rb
CHANGED
@@ -30,6 +30,8 @@ require "stripe/resources/event"
|
|
30
30
|
require "stripe/resources/exchange_rate"
|
31
31
|
require "stripe/resources/file"
|
32
32
|
require "stripe/resources/file_link"
|
33
|
+
require "stripe/resources/identity/verification_report"
|
34
|
+
require "stripe/resources/identity/verification_session"
|
33
35
|
require "stripe/resources/invoice"
|
34
36
|
require "stripe/resources/invoice_item"
|
35
37
|
require "stripe/resources/invoice_line_item"
|
@@ -45,12 +45,8 @@ module Stripe
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# @override To make id optional
|
48
|
-
def self.retrieve(id =
|
49
|
-
id
|
50
|
-
nil
|
51
|
-
else
|
52
|
-
Util.check_string_argument!(id)
|
53
|
-
end
|
48
|
+
def self.retrieve(id = nil, opts = {})
|
49
|
+
Util.check_string_argument!(id) if id
|
54
50
|
|
55
51
|
# Account used to be a singleton, where this method's signature was
|
56
52
|
# `(opts={})`. For the sake of not breaking folks who pass in an OAuth
|
@@ -136,11 +132,10 @@ module Stripe
|
|
136
132
|
client_id: client_id,
|
137
133
|
stripe_user_id: id,
|
138
134
|
}
|
135
|
+
opts = @opts.merge(Util.normalize_opts(opts))
|
139
136
|
OAuth.deauthorize(params, opts)
|
140
137
|
end
|
141
138
|
|
142
|
-
ARGUMENT_NOT_PROVIDED = Object.new
|
143
|
-
|
144
139
|
private def serialize_additional_owners(legal_entity, additional_owners)
|
145
140
|
original_value =
|
146
141
|
legal_entity
|
@@ -25,8 +25,9 @@ module Stripe
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
config = opts[:client]&.config || Stripe.config
|
28
29
|
opts = {
|
29
|
-
api_base:
|
30
|
+
api_base: config.uploads_base,
|
30
31
|
content_type: MultipartEncoder::MULTIPART_FORM_DATA,
|
31
32
|
}.merge(Util.normalize_opts(opts))
|
32
33
|
super
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# File generated from our OpenAPI spec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Stripe
|
5
|
+
module Identity
|
6
|
+
class VerificationSession < APIResource
|
7
|
+
extend Stripe::APIOperations::Create
|
8
|
+
extend Stripe::APIOperations::List
|
9
|
+
include Stripe::APIOperations::Save
|
10
|
+
|
11
|
+
OBJECT_NAME = "identity.verification_session"
|
12
|
+
|
13
|
+
custom_method :cancel, http_verb: :post
|
14
|
+
custom_method :redact, http_verb: :post
|
15
|
+
|
16
|
+
def cancel(params = {}, opts = {})
|
17
|
+
request_stripe_object(
|
18
|
+
method: :post,
|
19
|
+
path: resource_url + "/cancel",
|
20
|
+
params: params,
|
21
|
+
opts: opts
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def redact(params = {}, opts = {})
|
26
|
+
request_stripe_object(
|
27
|
+
method: :post,
|
28
|
+
path: resource_url + "/redact",
|
29
|
+
params: params,
|
30
|
+
opts: opts
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/stripe/stripe_client.rb
CHANGED
@@ -9,18 +9,35 @@ module Stripe
|
|
9
9
|
class StripeClient
|
10
10
|
# A set of all known thread contexts across all threads and a mutex to
|
11
11
|
# synchronize global access to them.
|
12
|
-
@thread_contexts_with_connection_managers =
|
12
|
+
@thread_contexts_with_connection_managers = Set.new
|
13
13
|
@thread_contexts_with_connection_managers_mutex = Mutex.new
|
14
14
|
@last_connection_manager_gc = Util.monotonic_time
|
15
15
|
|
16
|
-
# Initializes a new
|
17
|
-
|
18
|
-
# Takes a connection manager object for backwards compatibility only, and
|
19
|
-
# that use is DEPRECATED.
|
20
|
-
def initialize(_connection_manager = nil)
|
16
|
+
# Initializes a new StripeClient
|
17
|
+
def initialize(config_arg = {})
|
21
18
|
@system_profiler = SystemProfiler.new
|
22
19
|
@last_request_metrics = nil
|
23
|
-
|
20
|
+
|
21
|
+
@config = case config_arg
|
22
|
+
when Hash
|
23
|
+
Stripe.config.reverse_duplicate_merge(config_arg)
|
24
|
+
when Stripe::ConnectionManager
|
25
|
+
# Supports accepting a connection manager object for backwards
|
26
|
+
# compatibility only, and that use is DEPRECATED.
|
27
|
+
Stripe.config.dup
|
28
|
+
when Stripe::StripeConfiguration
|
29
|
+
config_arg
|
30
|
+
when String
|
31
|
+
Stripe.config.reverse_duplicate_merge(
|
32
|
+
{ api_key: config_arg }
|
33
|
+
)
|
34
|
+
else
|
35
|
+
raise ArgumentError, "Can't handle argument: #{config_arg}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :config
|
40
|
+
attr_reader :options
|
24
41
|
|
25
42
|
# Gets a currently active `StripeClient`. Set for the current thread when
|
26
43
|
# `StripeClient#request` is being run so that API operations being executed
|
@@ -37,36 +54,51 @@ module Stripe
|
|
37
54
|
# clears them from internal tracking in all connection managers across all
|
38
55
|
# threads.
|
39
56
|
#
|
57
|
+
# If passed a `config` object, only clear connection managers for that
|
58
|
+
# particular configuration.
|
59
|
+
#
|
40
60
|
# For internal use only. Does not provide a stable API and may be broken
|
41
61
|
# with future non-major changes.
|
42
|
-
def self.clear_all_connection_managers
|
62
|
+
def self.clear_all_connection_managers(config: nil)
|
43
63
|
# Just a quick path for when configuration is being set for the first
|
44
64
|
# time before any connections have been opened. There is technically some
|
45
65
|
# potential for thread raciness here, but not in a practical sense.
|
46
66
|
return if @thread_contexts_with_connection_managers.empty?
|
47
67
|
|
48
68
|
@thread_contexts_with_connection_managers_mutex.synchronize do
|
69
|
+
pruned_contexts = Set.new
|
70
|
+
|
49
71
|
@thread_contexts_with_connection_managers.each do |thread_context|
|
50
72
|
# Note that the thread context itself is not destroyed, but we clear
|
51
73
|
# its connection manager and remove our reference to it. If it ever
|
52
74
|
# makes a new request we'll give it a new connection manager and
|
53
75
|
# it'll go back into `@thread_contexts_with_connection_managers`.
|
54
|
-
thread_context.
|
55
|
-
|
76
|
+
thread_context.default_connection_managers.reject! do |cm_config, cm|
|
77
|
+
if config.nil? || config.key == cm_config
|
78
|
+
cm.clear
|
79
|
+
true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if thread_context.default_connection_managers.empty?
|
84
|
+
pruned_contexts << thread_context
|
85
|
+
end
|
56
86
|
end
|
57
|
-
|
87
|
+
|
88
|
+
@thread_contexts_with_connection_managers.subtract(pruned_contexts)
|
58
89
|
end
|
59
90
|
end
|
60
91
|
|
61
92
|
# A default client for the current thread.
|
62
93
|
def self.default_client
|
63
|
-
current_thread_context.default_client ||= StripeClient.new
|
94
|
+
current_thread_context.default_client ||= StripeClient.new(Stripe.config)
|
64
95
|
end
|
65
96
|
|
66
|
-
# A default connection manager for the current thread
|
67
|
-
|
68
|
-
|
69
|
-
|
97
|
+
# A default connection manager for the current thread scoped to the
|
98
|
+
# configuration object that may be provided.
|
99
|
+
def self.default_connection_manager(config = Stripe.config)
|
100
|
+
current_thread_context.default_connection_managers[config.key] ||= begin
|
101
|
+
connection_manager = ConnectionManager.new(config)
|
70
102
|
|
71
103
|
@thread_contexts_with_connection_managers_mutex.synchronize do
|
72
104
|
maybe_gc_connection_managers
|
@@ -80,8 +112,9 @@ module Stripe
|
|
80
112
|
# Checks if an error is a problem that we should retry on. This includes
|
81
113
|
# both socket errors that may represent an intermittent problem and some
|
82
114
|
# special HTTP statuses.
|
83
|
-
def self.should_retry?(error,
|
84
|
-
|
115
|
+
def self.should_retry?(error,
|
116
|
+
method:, num_retries:, config: Stripe.config)
|
117
|
+
return false if num_retries >= config.max_network_retries
|
85
118
|
|
86
119
|
case error
|
87
120
|
when Net::OpenTimeout, Net::ReadTimeout
|
@@ -127,13 +160,13 @@ module Stripe
|
|
127
160
|
end
|
128
161
|
end
|
129
162
|
|
130
|
-
def self.sleep_time(num_retries)
|
163
|
+
def self.sleep_time(num_retries, config: Stripe.config)
|
131
164
|
# Apply exponential backoff with initial_network_retry_delay on the
|
132
165
|
# number of num_retries so far as inputs. Do not allow the number to
|
133
166
|
# exceed max_network_retry_delay.
|
134
167
|
sleep_seconds = [
|
135
|
-
|
136
|
-
|
168
|
+
config.initial_network_retry_delay * (2**(num_retries - 1)),
|
169
|
+
config.max_network_retry_delay,
|
137
170
|
].min
|
138
171
|
|
139
172
|
# Apply some jitter by randomizing the value in the range of
|
@@ -141,9 +174,7 @@ module Stripe
|
|
141
174
|
sleep_seconds *= (0.5 * (1 + rand))
|
142
175
|
|
143
176
|
# But never sleep less than the base sleep seconds.
|
144
|
-
|
145
|
-
|
146
|
-
sleep_seconds
|
177
|
+
[config.initial_network_retry_delay, sleep_seconds].max
|
147
178
|
end
|
148
179
|
|
149
180
|
# Gets the connection manager in use for the current `StripeClient`.
|
@@ -187,8 +218,8 @@ module Stripe
|
|
187
218
|
raise ArgumentError, "path should be a string" \
|
188
219
|
unless path.is_a?(String)
|
189
220
|
|
190
|
-
api_base ||=
|
191
|
-
api_key ||=
|
221
|
+
api_base ||= config.api_base
|
222
|
+
api_key ||= config.api_key
|
192
223
|
params = Util.objects_to_ids(params)
|
193
224
|
|
194
225
|
check_api_key!(api_key)
|
@@ -231,10 +262,12 @@ module Stripe
|
|
231
262
|
context.query = query
|
232
263
|
|
233
264
|
http_resp = execute_request_with_rescues(method, api_base, context) do
|
234
|
-
self.class
|
235
|
-
|
236
|
-
|
237
|
-
|
265
|
+
self.class
|
266
|
+
.default_connection_manager(config)
|
267
|
+
.execute_request(method, url,
|
268
|
+
body: body,
|
269
|
+
headers: headers,
|
270
|
+
query: query)
|
238
271
|
end
|
239
272
|
|
240
273
|
begin
|
@@ -246,13 +279,21 @@ module Stripe
|
|
246
279
|
# If being called from `StripeClient#request`, put the last response in
|
247
280
|
# thread-local memory so that it can be returned to the user. Don't store
|
248
281
|
# anything otherwise so that we don't leak memory.
|
249
|
-
|
250
|
-
self.class.current_thread_context.last_responses[object_id] = resp
|
251
|
-
end
|
282
|
+
store_last_response(object_id, resp)
|
252
283
|
|
253
284
|
[resp, api_key]
|
254
285
|
end
|
255
286
|
|
287
|
+
def store_last_response(object_id, resp)
|
288
|
+
return unless last_response_has_key?(object_id)
|
289
|
+
|
290
|
+
self.class.current_thread_context.last_responses[object_id] = resp
|
291
|
+
end
|
292
|
+
|
293
|
+
def last_response_has_key?(object_id)
|
294
|
+
self.class.current_thread_context.last_responses&.key?(object_id)
|
295
|
+
end
|
296
|
+
|
256
297
|
#
|
257
298
|
# private
|
258
299
|
#
|
@@ -328,11 +369,6 @@ module Stripe
|
|
328
369
|
# the user hasn't specified their own.
|
329
370
|
attr_accessor :default_client
|
330
371
|
|
331
|
-
# A default `ConnectionManager` for the thread. Normally shared between
|
332
|
-
# all `StripeClient` objects on a particular thread, and created so as to
|
333
|
-
# minimize the number of open connections that an application needs.
|
334
|
-
attr_accessor :default_connection_manager
|
335
|
-
|
336
372
|
# A temporary map of object IDs to responses from last executed API
|
337
373
|
# calls. Used to return a responses from calls to `StripeClient#request`.
|
338
374
|
#
|
@@ -345,6 +381,17 @@ module Stripe
|
|
345
381
|
# because that's wrapped in an `ensure` block, they should never leave
|
346
382
|
# garbage in `Thread.current`.
|
347
383
|
attr_accessor :last_responses
|
384
|
+
|
385
|
+
# A map of connection mangers for the thread. Normally shared between
|
386
|
+
# all `StripeClient` objects on a particular thread, and created so as to
|
387
|
+
# minimize the number of open connections that an application needs.
|
388
|
+
def default_connection_managers
|
389
|
+
@default_connection_managers ||= {}
|
390
|
+
end
|
391
|
+
|
392
|
+
def reset_connection_managers
|
393
|
+
@default_connection_managers = {}
|
394
|
+
end
|
348
395
|
end
|
349
396
|
|
350
397
|
# Access data stored for `StripeClient` within the thread's current
|
@@ -380,24 +427,32 @@ module Stripe
|
|
380
427
|
last_used_threshold =
|
381
428
|
Util.monotonic_time - CONNECTION_MANAGER_GC_LAST_USED_EXPIRY
|
382
429
|
|
383
|
-
|
430
|
+
pruned_contexts = []
|
431
|
+
@thread_contexts_with_connection_managers.each do |thread_context|
|
432
|
+
thread_context
|
433
|
+
.default_connection_managers
|
434
|
+
.each do |config_key, connection_manager|
|
435
|
+
next if connection_manager.last_used > last_used_threshold
|
436
|
+
|
437
|
+
connection_manager.clear
|
438
|
+
thread_context.default_connection_managers.delete(config_key)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
384
442
|
@thread_contexts_with_connection_managers.each do |thread_context|
|
385
|
-
|
386
|
-
next if connection_manager.last_used > last_used_threshold
|
443
|
+
next unless thread_context.default_connection_managers.empty?
|
387
444
|
|
388
|
-
|
389
|
-
thread_context.default_connection_manager = nil
|
390
|
-
pruned_thread_contexts << thread_context
|
445
|
+
pruned_contexts << thread_context
|
391
446
|
end
|
392
447
|
|
393
|
-
@thread_contexts_with_connection_managers -=
|
448
|
+
@thread_contexts_with_connection_managers -= pruned_contexts
|
394
449
|
@last_connection_manager_gc = Util.monotonic_time
|
395
450
|
|
396
|
-
|
451
|
+
pruned_contexts.count
|
397
452
|
end
|
398
453
|
|
399
454
|
private def api_url(url = "", api_base = nil)
|
400
|
-
(api_base ||
|
455
|
+
(api_base || config.api_base) + url
|
401
456
|
end
|
402
457
|
|
403
458
|
private def check_api_key!(api_key)
|
@@ -471,7 +526,7 @@ module Stripe
|
|
471
526
|
notify_request_end(context, request_duration, http_status,
|
472
527
|
num_retries, user_data)
|
473
528
|
|
474
|
-
if
|
529
|
+
if config.enable_telemetry? && context.request_id
|
475
530
|
request_duration_ms = (request_duration * 1000).to_i
|
476
531
|
@last_request_metrics =
|
477
532
|
StripeRequestMetrics.new(context.request_id, request_duration_ms)
|
@@ -498,9 +553,12 @@ module Stripe
|
|
498
553
|
notify_request_end(context, request_duration, http_status, num_retries,
|
499
554
|
user_data)
|
500
555
|
|
501
|
-
if self.class.should_retry?(e,
|
556
|
+
if self.class.should_retry?(e,
|
557
|
+
method: method,
|
558
|
+
num_retries: num_retries,
|
559
|
+
config: config)
|
502
560
|
num_retries += 1
|
503
|
-
sleep self.class.sleep_time(num_retries)
|
561
|
+
sleep self.class.sleep_time(num_retries, config: config)
|
504
562
|
retry
|
505
563
|
end
|
506
564
|
|
@@ -622,7 +680,8 @@ module Stripe
|
|
622
680
|
error_param: error_data[:param],
|
623
681
|
error_type: error_data[:type],
|
624
682
|
idempotency_key: context.idempotency_key,
|
625
|
-
request_id: context.request_id
|
683
|
+
request_id: context.request_id,
|
684
|
+
config: config)
|
626
685
|
|
627
686
|
# The standard set of arguments that can be used to initialize most of
|
628
687
|
# the exceptions.
|
@@ -671,7 +730,8 @@ module Stripe
|
|
671
730
|
error_code: error_code,
|
672
731
|
error_description: description,
|
673
732
|
idempotency_key: context.idempotency_key,
|
674
|
-
request_id: context.request_id
|
733
|
+
request_id: context.request_id,
|
734
|
+
config: config)
|
675
735
|
|
676
736
|
args = {
|
677
737
|
http_status: resp.http_status, http_body: resp.http_body,
|
@@ -703,7 +763,8 @@ module Stripe
|
|
703
763
|
Util.log_error("Stripe network error",
|
704
764
|
error_message: error.message,
|
705
765
|
idempotency_key: context.idempotency_key,
|
706
|
-
request_id: context.request_id
|
766
|
+
request_id: context.request_id,
|
767
|
+
config: config)
|
707
768
|
|
708
769
|
errors, message = NETWORK_ERROR_MESSAGES_MAP.detect do |(e, _)|
|
709
770
|
error.is_a?(e)
|
@@ -714,7 +775,7 @@ module Stripe
|
|
714
775
|
"with Stripe. Please let us know at support@stripe.com."
|
715
776
|
end
|
716
777
|
|
717
|
-
api_base ||=
|
778
|
+
api_base ||= config.api_base
|
718
779
|
message = message % api_base
|
719
780
|
|
720
781
|
message += " Request was retried #{num_retries} times." if num_retries > 0
|
@@ -735,7 +796,7 @@ module Stripe
|
|
735
796
|
"Content-Type" => "application/x-www-form-urlencoded",
|
736
797
|
}
|
737
798
|
|
738
|
-
if
|
799
|
+
if config.enable_telemetry? && !@last_request_metrics.nil?
|
739
800
|
headers["X-Stripe-Client-Telemetry"] = JSON.generate(
|
740
801
|
last_request_metrics: @last_request_metrics.payload
|
741
802
|
)
|
@@ -743,12 +804,12 @@ module Stripe
|
|
743
804
|
|
744
805
|
# It is only safe to retry network failures on post and delete
|
745
806
|
# requests if we add an Idempotency-Key header
|
746
|
-
if %i[post delete].include?(method) &&
|
807
|
+
if %i[post delete].include?(method) && config.max_network_retries > 0
|
747
808
|
headers["Idempotency-Key"] ||= SecureRandom.uuid
|
748
809
|
end
|
749
810
|
|
750
|
-
headers["Stripe-Version"] =
|
751
|
-
headers["Stripe-Account"] =
|
811
|
+
headers["Stripe-Version"] = config.api_version if config.api_version
|
812
|
+
headers["Stripe-Account"] = config.stripe_account if config.stripe_account
|
752
813
|
|
753
814
|
user_agent = @system_profiler.user_agent
|
754
815
|
begin
|
@@ -772,11 +833,13 @@ module Stripe
|
|
772
833
|
idempotency_key: context.idempotency_key,
|
773
834
|
method: context.method,
|
774
835
|
num_retries: num_retries,
|
775
|
-
path: context.path
|
836
|
+
path: context.path,
|
837
|
+
config: config)
|
776
838
|
Util.log_debug("Request details",
|
777
839
|
body: context.body,
|
778
840
|
idempotency_key: context.idempotency_key,
|
779
|
-
query: context.query
|
841
|
+
query: context.query,
|
842
|
+
config: config)
|
780
843
|
end
|
781
844
|
|
782
845
|
private def log_response(context, request_start, status, body)
|
@@ -788,11 +851,13 @@ module Stripe
|
|
788
851
|
method: context.method,
|
789
852
|
path: context.path,
|
790
853
|
request_id: context.request_id,
|
791
|
-
status: status
|
854
|
+
status: status,
|
855
|
+
config: config)
|
792
856
|
Util.log_debug("Response details",
|
793
857
|
body: body,
|
794
858
|
idempotency_key: context.idempotency_key,
|
795
|
-
request_id: context.request_id
|
859
|
+
request_id: context.request_id,
|
860
|
+
config: config)
|
796
861
|
|
797
862
|
return unless context.request_id
|
798
863
|
|
@@ -800,7 +865,8 @@ module Stripe
|
|
800
865
|
idempotency_key: context.idempotency_key,
|
801
866
|
request_id: context.request_id,
|
802
867
|
url: Util.request_id_dashboard_url(context.request_id,
|
803
|
-
context.api_key)
|
868
|
+
context.api_key),
|
869
|
+
config: config)
|
804
870
|
end
|
805
871
|
|
806
872
|
private def log_response_error(context, request_start, error)
|
@@ -810,7 +876,8 @@ module Stripe
|
|
810
876
|
error_message: error.message,
|
811
877
|
idempotency_key: context.idempotency_key,
|
812
878
|
method: context.method,
|
813
|
-
path: context.path
|
879
|
+
path: context.path,
|
880
|
+
config: config)
|
814
881
|
end
|
815
882
|
|
816
883
|
# RequestLogContext stores information about a request that's begin made so
|