sentry-ruby-core 4.8.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/Gemfile +3 -0
  4. data/README.md +2 -0
  5. data/lib/sentry/background_worker.rb +33 -3
  6. data/lib/sentry/backtrace.rb +1 -3
  7. data/lib/sentry/breadcrumb/sentry_logger.rb +2 -0
  8. data/lib/sentry/breadcrumb.rb +24 -3
  9. data/lib/sentry/breadcrumb_buffer.rb +16 -0
  10. data/lib/sentry/client.rb +38 -2
  11. data/lib/sentry/configuration.rb +94 -41
  12. data/lib/sentry/core_ext/object/deep_dup.rb +2 -0
  13. data/lib/sentry/core_ext/object/duplicable.rb +1 -0
  14. data/lib/sentry/dsn.rb +2 -0
  15. data/lib/sentry/envelope.rb +45 -0
  16. data/lib/sentry/event.rb +55 -18
  17. data/lib/sentry/exceptions.rb +2 -0
  18. data/lib/sentry/hub.rb +38 -2
  19. data/lib/sentry/integrable.rb +2 -0
  20. data/lib/sentry/interface.rb +3 -10
  21. data/lib/sentry/interfaces/exception.rb +14 -3
  22. data/lib/sentry/interfaces/request.rb +37 -20
  23. data/lib/sentry/interfaces/single_exception.rb +2 -0
  24. data/lib/sentry/interfaces/stacktrace.rb +6 -0
  25. data/lib/sentry/interfaces/stacktrace_builder.rb +39 -10
  26. data/lib/sentry/interfaces/threads.rb +12 -2
  27. data/lib/sentry/linecache.rb +3 -0
  28. data/lib/sentry/net/http.rb +54 -65
  29. data/lib/sentry/rack/capture_exceptions.rb +28 -24
  30. data/lib/sentry/rack.rb +2 -0
  31. data/lib/sentry/rake.rb +16 -6
  32. data/lib/sentry/redis.rb +90 -0
  33. data/lib/sentry/release_detector.rb +3 -0
  34. data/lib/sentry/scope.rb +85 -6
  35. data/lib/sentry/session.rb +35 -0
  36. data/lib/sentry/session_flusher.rb +79 -0
  37. data/lib/sentry/span.rb +84 -8
  38. data/lib/sentry/transaction.rb +48 -14
  39. data/lib/sentry/transaction_event.rb +8 -0
  40. data/lib/sentry/transport/configuration.rb +3 -2
  41. data/lib/sentry/transport/dummy_transport.rb +8 -1
  42. data/lib/sentry/transport/http_transport.rb +55 -42
  43. data/lib/sentry/transport.rb +79 -37
  44. data/lib/sentry/utils/argument_checking_helper.rb +2 -0
  45. data/lib/sentry/utils/custom_inspection.rb +2 -0
  46. data/lib/sentry/utils/exception_cause_chain.rb +2 -0
  47. data/lib/sentry/utils/logging_helper.rb +6 -4
  48. data/lib/sentry/utils/real_ip.rb +2 -0
  49. data/lib/sentry/utils/request_id.rb +2 -0
  50. data/lib/sentry/version.rb +3 -1
  51. data/lib/sentry-ruby.rb +212 -41
  52. data/sentry-ruby-core.gemspec +0 -1
  53. data/sentry-ruby.gemspec +0 -1
  54. metadata +7 -16
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sentry
4
+ class SessionFlusher
5
+ include LoggingHelper
6
+
7
+ FLUSH_INTERVAL = 60
8
+
9
+ def initialize(configuration, client)
10
+ @thread = nil
11
+ @client = client
12
+ @pending_aggregates = {}
13
+ @release = configuration.release
14
+ @environment = configuration.environment
15
+ @logger = configuration.logger
16
+
17
+ log_debug("[Sessions] Sessions won't be captured without a valid release") unless @release
18
+ end
19
+
20
+ def flush
21
+ return if @pending_aggregates.empty?
22
+ envelope = pending_envelope
23
+
24
+ Sentry.background_worker.perform do
25
+ @client.transport.send_envelope(envelope)
26
+ end
27
+
28
+ @pending_aggregates = {}
29
+ end
30
+
31
+ def add_session(session)
32
+ return unless @release
33
+
34
+ ensure_thread
35
+
36
+ return unless Session::AGGREGATE_STATUSES.include?(session.status)
37
+ @pending_aggregates[session.aggregation_key] ||= init_aggregates(session.aggregation_key)
38
+ @pending_aggregates[session.aggregation_key][session.status] += 1
39
+ end
40
+
41
+ def kill
42
+ @thread&.kill
43
+ end
44
+
45
+ private
46
+
47
+ def init_aggregates(aggregation_key)
48
+ aggregates = { started: aggregation_key.iso8601 }
49
+ Session::AGGREGATE_STATUSES.each { |k| aggregates[k] = 0 }
50
+ aggregates
51
+ end
52
+
53
+ def pending_envelope
54
+ envelope = Envelope.new
55
+
56
+ header = { type: 'sessions' }
57
+ payload = { attrs: attrs, aggregates: @pending_aggregates.values }
58
+
59
+ envelope.add_item(header, payload)
60
+ envelope
61
+ end
62
+
63
+ def attrs
64
+ { release: @release, environment: @environment }
65
+ end
66
+
67
+ def ensure_thread
68
+ return if @thread&.alive?
69
+
70
+ @thread = Thread.new do
71
+ loop do
72
+ sleep(FLUSH_INTERVAL)
73
+ flush
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+ end
data/lib/sentry/span.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "securerandom"
3
4
 
4
5
  module Sentry
@@ -17,9 +18,49 @@ module Sentry
17
18
  504 => "deadline_exceeded"
18
19
  }
19
20
 
20
-
21
- attr_reader :trace_id, :span_id, :parent_span_id, :sampled, :start_timestamp, :timestamp, :description, :op, :status, :tags, :data
22
- attr_accessor :span_recorder, :transaction
21
+ # An uuid that can be used to identify a trace.
22
+ # @return [String]
23
+ attr_reader :trace_id
24
+ # An uuid that can be used to identify the span.
25
+ # @return [String]
26
+ attr_reader :span_id
27
+ # Span parent's span_id.
28
+ # @return [String]
29
+ attr_reader :parent_span_id
30
+ # Sampling result of the span.
31
+ # @return [Boolean, nil]
32
+ attr_reader :sampled
33
+ # Starting timestamp of the span.
34
+ # @return [Float]
35
+ attr_reader :start_timestamp
36
+ # Finishing timestamp of the span.
37
+ # @return [Float]
38
+ attr_reader :timestamp
39
+ # Span description
40
+ # @return [String]
41
+ attr_reader :description
42
+ # Span operation
43
+ # @return [String]
44
+ attr_reader :op
45
+ # Span status
46
+ # @return [String]
47
+ attr_reader :status
48
+ # Span tags
49
+ # @return [Hash]
50
+ attr_reader :tags
51
+ # Span data
52
+ # @return [Hash]
53
+ attr_reader :data
54
+
55
+ # The SpanRecorder the current span belongs to.
56
+ # SpanRecorder holds all spans under the same Transaction object (including the Transaction itself).
57
+ # @return [SpanRecorder]
58
+ attr_accessor :span_recorder
59
+
60
+ # The Transaction object the Span belongs to.
61
+ # Every span needs to be attached to a Transaction and their child spans will also inherit the same transaction.
62
+ # @return [Transaction]
63
+ attr_accessor :transaction
23
64
 
24
65
  def initialize(
25
66
  description: nil,
@@ -44,6 +85,8 @@ module Sentry
44
85
  @tags = {}
45
86
  end
46
87
 
88
+ # Finishes the span by adding a timestamp.
89
+ # @return [self]
47
90
  def finish
48
91
  # already finished
49
92
  return if @timestamp
@@ -52,6 +95,8 @@ module Sentry
52
95
  self
53
96
  end
54
97
 
98
+ # Generates a trace string that can be used to connect other transactions.
99
+ # @return [String]
55
100
  def to_sentry_trace
56
101
  sampled_flag = ""
57
102
  sampled_flag = @sampled ? 1 : 0 unless @sampled.nil?
@@ -59,6 +104,7 @@ module Sentry
59
104
  "#{@trace_id}-#{@span_id}-#{sampled_flag}"
60
105
  end
61
106
 
107
+ # @return [Hash]
62
108
  def to_hash
63
109
  {
64
110
  trace_id: @trace_id,
@@ -74,6 +120,8 @@ module Sentry
74
120
  }
75
121
  end
76
122
 
123
+ # Returns the span's context that can be used to embed in an Event.
124
+ # @return [Hash]
77
125
  def get_trace_context
78
126
  {
79
127
  trace_id: @trace_id,
@@ -85,9 +133,11 @@ module Sentry
85
133
  }
86
134
  end
87
135
 
88
- def start_child(**options)
89
- options = options.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
90
- new_span = Span.new(**options)
136
+ # Starts a child span with given attributes.
137
+ # @param attributes [Hash] the attributes for the child span.
138
+ def start_child(**attributes)
139
+ attributes = attributes.dup.merge(trace_id: @trace_id, parent_span_id: @span_id, sampled: @sampled)
140
+ new_span = Span.new(**attributes)
91
141
  new_span.transaction = transaction
92
142
  new_span.span_recorder = span_recorder
93
143
 
@@ -98,8 +148,17 @@ module Sentry
98
148
  new_span
99
149
  end
100
150
 
101
- def with_child_span(**options, &block)
102
- child_span = start_child(**options)
151
+ # Starts a child span, yield it to the given block, and then finish the span after the block is executed.
152
+ # @example
153
+ # span.with_child_span do |child_span|
154
+ # # things happen here will be recorded in a child span
155
+ # end
156
+ #
157
+ # @param attributes [Hash] the attributes for the child span.
158
+ # @param block [Proc] the action to be recorded in the child span.
159
+ # @yieldparam child_span [Span]
160
+ def with_child_span(**attributes, &block)
161
+ child_span = start_child(**attributes)
103
162
 
104
163
  yield(child_span)
105
164
 
@@ -110,22 +169,33 @@ module Sentry
110
169
  dup
111
170
  end
112
171
 
172
+ # Sets the span's operation.
173
+ # @param op [String] operation of the span.
113
174
  def set_op(op)
114
175
  @op = op
115
176
  end
116
177
 
178
+ # Sets the span's description.
179
+ # @param description [String] description of the span.
117
180
  def set_description(description)
118
181
  @description = description
119
182
  end
120
183
 
184
+
185
+ # Sets the span's status.
186
+ # @param satus [String] status of the span.
121
187
  def set_status(status)
122
188
  @status = status
123
189
  end
124
190
 
191
+ # Sets the span's finish timestamp.
192
+ # @param timestamp [Float] finished time in float format (most precise).
125
193
  def set_timestamp(timestamp)
126
194
  @timestamp = timestamp
127
195
  end
128
196
 
197
+ # Sets the span's status with given http status code.
198
+ # @param status_code [String] example: "500".
129
199
  def set_http_status(status_code)
130
200
  status_code = status_code.to_i
131
201
  set_data("status_code", status_code)
@@ -139,10 +209,16 @@ module Sentry
139
209
  set_status(status)
140
210
  end
141
211
 
212
+ # Inserts a key-value pair to the span's data payload.
213
+ # @param key [String, Symbol]
214
+ # @param value [Object]
142
215
  def set_data(key, value)
143
216
  @data[key] = value
144
217
  end
145
218
 
219
+ # Sets a tag to the span.
220
+ # @param key [String, Symbol]
221
+ # @param value [String]
146
222
  def set_tag(key, value)
147
223
  @tags[key] = value
148
224
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  class Transaction < Span
3
5
  SENTRY_TRACE_REGEXP = Regexp.new(
@@ -12,7 +14,22 @@ module Sentry
12
14
 
13
15
  include LoggingHelper
14
16
 
15
- attr_reader :name, :parent_sampled, :hub, :configuration, :logger
17
+ # The name of the transaction.
18
+ # @return [String]
19
+ attr_reader :name
20
+
21
+ # The sampling decision of the parent transaction, which will be considered when making the current transaction's sampling decision.
22
+ # @return [String]
23
+ attr_reader :parent_sampled
24
+
25
+ # @deprecated Use Sentry.get_current_hub instead.
26
+ attr_reader :hub
27
+
28
+ # @deprecated Use Sentry.configuration instead.
29
+ attr_reader :configuration
30
+
31
+ # @deprecated Use Sentry.logger instead.
32
+ attr_reader :logger
16
33
 
17
34
  def initialize(name: nil, parent_sampled: nil, hub:, **options)
18
35
  super(**options)
@@ -21,11 +38,23 @@ module Sentry
21
38
  @parent_sampled = parent_sampled
22
39
  @transaction = self
23
40
  @hub = hub
24
- @configuration = hub.configuration
25
- @logger = configuration.logger
41
+ @configuration = hub.configuration # to be removed
42
+ @tracing_enabled = hub.configuration.tracing_enabled?
43
+ @traces_sampler = hub.configuration.traces_sampler
44
+ @traces_sample_rate = hub.configuration.traces_sample_rate
45
+ @logger = hub.configuration.logger
26
46
  init_span_recorder
27
47
  end
28
48
 
49
+ # Initalizes a Transaction instance with a Sentry trace string from another transaction (usually from an external request).
50
+ #
51
+ # The original transaction will become the parent of the new Transaction instance. And they will share the same `trace_id`.
52
+ #
53
+ # The child transaction will also store the parent's sampling decision in its `parent_sampled` attribute.
54
+ # @param sentry_trace [String] the trace string from the previous transaction.
55
+ # @param hub [Hub] the hub that'll be responsible for sending this transaction when it's finished.
56
+ # @param options [Hash] the options you want to use to initialize a Transaction instance.
57
+ # @return [Transaction, nil]
29
58
  def self.from_sentry_trace(sentry_trace, hub: Sentry.get_current_hub, **options)
30
59
  return unless hub.configuration.tracing_enabled?
31
60
  return unless sentry_trace
@@ -44,12 +73,14 @@ module Sentry
44
73
  new(trace_id: trace_id, parent_span_id: parent_span_id, parent_sampled: parent_sampled, hub: hub, **options)
45
74
  end
46
75
 
76
+ # @return [Hash]
47
77
  def to_hash
48
78
  hash = super
49
79
  hash.merge!(name: @name, sampled: @sampled, parent_sampled: @parent_sampled)
50
80
  hash
51
81
  end
52
82
 
83
+ # @return [Transaction]
53
84
  def deep_dup
54
85
  copy = super
55
86
  copy.init_span_recorder(@span_recorder.max_length)
@@ -63,23 +94,24 @@ module Sentry
63
94
  copy
64
95
  end
65
96
 
97
+ # Sets initial sampling decision of the transaction.
98
+ # @param sampling_context [Hash] a context Hash that'll be passed to `traces_sampler` (if provided).
99
+ # @return [void]
66
100
  def set_initial_sample_decision(sampling_context:)
67
- unless configuration.tracing_enabled?
101
+ unless @tracing_enabled
68
102
  @sampled = false
69
103
  return
70
104
  end
71
105
 
72
106
  return unless @sampled.nil?
73
107
 
74
- traces_sampler = configuration.traces_sampler
75
-
76
108
  sample_rate =
77
- if traces_sampler.is_a?(Proc)
78
- traces_sampler.call(sampling_context)
109
+ if @traces_sampler.is_a?(Proc)
110
+ @traces_sampler.call(sampling_context)
79
111
  elsif !sampling_context[:parent_sampled].nil?
80
112
  sampling_context[:parent_sampled]
81
113
  else
82
- configuration.traces_sample_rate
114
+ @traces_sample_rate
83
115
  end
84
116
 
85
117
  transaction_description = generate_transaction_description
@@ -111,6 +143,9 @@ module Sentry
111
143
  end
112
144
  end
113
145
 
146
+ # Finishes the transaction's recording and send it to Sentry.
147
+ # @param hub [Hub] the hub that'll send this transaction. (Deprecated)
148
+ # @return [TransactionEvent]
114
149
  def finish(hub: nil)
115
150
  if hub
116
151
  log_warn(
@@ -129,13 +164,12 @@ module Sentry
129
164
  @name = UNLABELD_NAME
130
165
  end
131
166
 
132
- unless @sampled || @parent_sampled
167
+ if @sampled
168
+ event = hub.current_client.event_from_transaction(self)
169
+ hub.capture_event(event)
170
+ else
133
171
  hub.current_client.transport.record_lost_event(:sample_rate, 'transaction')
134
- return
135
172
  end
136
-
137
- event = hub.current_client.event_from_transaction(self)
138
- hub.capture_event(event)
139
173
  end
140
174
 
141
175
  protected
@@ -16,17 +16,25 @@ module Sentry
16
16
  attr_writer(*WRITER_ATTRIBUTES)
17
17
  attr_reader(*SERIALIZEABLE_ATTRIBUTES)
18
18
 
19
+ # @return [<Array[Span]>]
19
20
  attr_accessor :spans
20
21
 
22
+ # @param configuration [Configuration]
23
+ # @param integration_meta [Hash, nil]
24
+ # @param message [String, nil]
21
25
  def initialize(configuration:, integration_meta: nil, message: nil)
22
26
  super
23
27
  @type = TYPE
24
28
  end
25
29
 
30
+ # Sets the event's start_timestamp.
31
+ # @param time [Time, Float]
32
+ # @return [void]
26
33
  def start_timestamp=(time)
27
34
  @start_timestamp = time.is_a?(Time) ? time.to_f : time
28
35
  end
29
36
 
37
+ # @return [Hash]
30
38
  def to_hash
31
39
  data = super
32
40
  data[:spans] = @spans.map(&:to_hash) if @spans
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  class Transport
3
5
  class Configuration
4
- attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :http_adapter, :faraday_builder,
5
- :encoding
6
+ attr_accessor :timeout, :open_timeout, :proxy, :ssl, :ssl_ca_file, :ssl_verification, :encoding
6
7
  attr_reader :transport_class
7
8
 
8
9
  def initialize
@@ -1,14 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sentry
2
4
  class DummyTransport < Transport
3
- attr_accessor :events
5
+ attr_accessor :events, :envelopes
4
6
 
5
7
  def initialize(*)
6
8
  super
7
9
  @events = []
10
+ @envelopes = []
8
11
  end
9
12
 
10
13
  def send_event(event)
11
14
  @events << event
12
15
  end
16
+
17
+ def send_envelope(envelope)
18
+ @envelopes << envelope
19
+ end
13
20
  end
14
21
  end
@@ -1,5 +1,7 @@
1
- require 'faraday'
2
- require 'zlib'
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "zlib"
3
5
 
4
6
  module Sentry
5
7
  class HTTPTransport < Transport
@@ -10,14 +12,13 @@ module Sentry
10
12
  DEFAULT_DELAY = 60
11
13
  RETRY_AFTER_HEADER = "retry-after"
12
14
  RATE_LIMIT_HEADER = "x-sentry-rate-limits"
13
-
14
- attr_reader :conn, :adapter
15
+ USER_AGENT = "sentry-ruby/#{Sentry::VERSION}"
15
16
 
16
17
  def initialize(*args)
17
18
  super
18
- @adapter = @transport_configuration.http_adapter || Faraday.default_adapter
19
- @conn = set_conn
20
19
  @endpoint = @dsn.envelope_endpoint
20
+
21
+ log_debug("Sentry HTTP Transport will connect to #{@dsn.server}")
21
22
  end
22
23
 
23
24
  def send_data(data)
@@ -28,29 +29,37 @@ module Sentry
28
29
  encoding = GZIP_ENCODING
29
30
  end
30
31
 
31
- response = conn.post @endpoint do |req|
32
- req.headers['Content-Type'] = CONTENT_TYPE
33
- req.headers['Content-Encoding'] = encoding
34
- req.headers['X-Sentry-Auth'] = generate_auth_header
35
- req.body = data
32
+ headers = {
33
+ 'Content-Type' => CONTENT_TYPE,
34
+ 'Content-Encoding' => encoding,
35
+ 'X-Sentry-Auth' => generate_auth_header,
36
+ 'User-Agent' => USER_AGENT
37
+ }
38
+
39
+ response = conn.start do |http|
40
+ request = ::Net::HTTP::Post.new(@endpoint, headers)
41
+ request.body = data
42
+ http.request(request)
36
43
  end
37
44
 
38
- if has_rate_limited_header?(response.headers)
39
- handle_rate_limited_response(response.headers)
40
- end
41
- rescue Faraday::Error => e
42
- error_info = e.message
45
+ if response.code.match?(/\A2\d{2}/)
46
+ if has_rate_limited_header?(response)
47
+ handle_rate_limited_response(response)
48
+ end
49
+ else
50
+ error_info = "the server responded with status #{response.code}"
43
51
 
44
- if e.response
45
- if e.response[:status] == 429
46
- handle_rate_limited_response(e.response[:headers])
52
+ if response.code == "429"
53
+ handle_rate_limited_response(response)
47
54
  else
48
- error_info += "\nbody: #{e.response[:body]}"
49
- error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}" if e.response[:headers]['x-sentry-error']
55
+ error_info += "\nbody: #{response.body}"
56
+ error_info += " Error in headers is: #{response['x-sentry-error']}" if response['x-sentry-error']
50
57
  end
51
- end
52
58
 
53
- raise Sentry::ExternalError, error_info
59
+ raise Sentry::ExternalError, error_info
60
+ end
61
+ rescue SocketError => e
62
+ raise Sentry::ExternalError.new(e.message)
54
63
  end
55
64
 
56
65
  private
@@ -117,32 +126,36 @@ module Sentry
117
126
  @transport_configuration.encoding == GZIP_ENCODING && data.bytesize >= GZIP_THRESHOLD
118
127
  end
119
128
 
120
- def set_conn
121
- server = @dsn.server
129
+ def conn
130
+ server = URI(@dsn.server)
122
131
 
123
- log_debug("Sentry HTTP Transport connecting to #{server}")
132
+ connection =
133
+ if proxy = @transport_configuration.proxy
134
+ ::Net::HTTP.new(server.hostname, server.port, proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password])
135
+ else
136
+ ::Net::HTTP.new(server.hostname, server.port, nil)
137
+ end
124
138
 
125
- Faraday.new(server, :ssl => ssl_configuration, :proxy => @transport_configuration.proxy) do |builder|
126
- @transport_configuration.faraday_builder&.call(builder)
127
- builder.response :raise_error
128
- builder.options.merge! faraday_opts
129
- builder.headers[:user_agent] = "sentry-ruby/#{Sentry::VERSION}"
130
- builder.adapter(*adapter)
131
- end
132
- end
139
+ connection.use_ssl = server.scheme == "https"
140
+ connection.read_timeout = @transport_configuration.timeout
141
+ connection.write_timeout = @transport_configuration.timeout if connection.respond_to?(:write_timeout)
142
+ connection.open_timeout = @transport_configuration.open_timeout
133
143
 
134
- # TODO: deprecate and replace where possible w/Faraday Builder
135
- def faraday_opts
136
- [:timeout, :open_timeout].each_with_object({}) do |opt, memo|
137
- memo[opt] = @transport_configuration.public_send(opt) if @transport_configuration.public_send(opt)
144
+ ssl_configuration.each do |key, value|
145
+ connection.send("#{key}=", value)
138
146
  end
147
+
148
+ connection
139
149
  end
140
150
 
141
151
  def ssl_configuration
142
- (@transport_configuration.ssl || {}).merge(
143
- :verify => @transport_configuration.ssl_verification,
144
- :ca_file => @transport_configuration.ssl_ca_file
145
- )
152
+ configuration = {
153
+ verify: @transport_configuration.ssl_verification,
154
+ ca_file: @transport_configuration.ssl_ca_file
155
+ }.merge(@transport_configuration.ssl || {})
156
+
157
+ configuration[:verify_mode] = configuration.delete(:verify) ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
158
+ configuration
146
159
  end
147
160
  end
148
161
  end