Class: Sentry::HTTPTransport
- Defined in:
- lib/sentry/transport/http_transport.rb
Direct Known Subclasses
Constant Summary collapse
- GZIP_ENCODING =
"gzip"
- GZIP_THRESHOLD =
1024 * 30
- CONTENT_TYPE =
"application/x-sentry-envelope"
- DEFAULT_DELAY =
60
- RETRY_AFTER_HEADER =
"retry-after"
- RATE_LIMIT_HEADER =
"x-sentry-rate-limits"
- USER_AGENT =
"sentry-ruby/#{Sentry::VERSION}"
- HTTP_ERRORS =
The list of errors ::Net::HTTP is known to raise See github.com/ruby/ruby/blob/b0c639f249165d759596f9579fa985cb30533de6/lib/bundler/fetcher.rb#L281-L286
[ Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Zlib::BufError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED ].freeze
Constants inherited from Transport
Transport::CLIENT_REPORT_INTERVAL, Transport::CLIENT_REPORT_REASONS, Transport::PROTOCOL_VERSION
Instance Attribute Summary
Attributes inherited from Transport
#discarded_events, #last_client_report_sent, #rate_limits
Instance Method Summary collapse
- #conn ⇒ Object
- #do_request(endpoint, headers, body) ⇒ Object
- #endpoint ⇒ Object
- #generate_auth_header ⇒ Object
-
#initialize(*args) ⇒ HTTPTransport
constructor
A new instance of HTTPTransport.
- #send_data(data) ⇒ Object
Methods inherited from Transport
#any_rate_limited?, #envelope_from_event, #flush, #is_rate_limited?, #record_lost_event, #send_envelope, #send_event, #serialize_envelope
Constructor Details
#initialize(*args) ⇒ HTTPTransport
Returns a new instance of HTTPTransport.
26 27 28 29 |
# File 'lib/sentry/transport/http_transport.rb', line 26 def initialize(*args) super log_debug("Sentry HTTP Transport will connect to #{@dsn.server}") if @dsn end |
Instance Method Details
#conn ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/sentry/transport/http_transport.rb', line 85 def conn server = URI(@dsn.server) # connection respects proxy setting from @transport_configuration, or environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) # Net::HTTP will automatically read the env vars. # See https://ruby-doc.org/3.2.2/stdlibs/net/Net/HTTP.html#class-Net::HTTP-label-Proxies connection = if proxy = normalize_proxy(@transport_configuration.proxy) ::Net::HTTP.new(server.hostname, server.port, proxy[:uri].hostname, proxy[:uri].port, proxy[:user], proxy[:password]) else ::Net::HTTP.new(server.hostname, server.port) end connection.use_ssl = server.scheme == "https" connection.read_timeout = @transport_configuration.timeout connection.write_timeout = @transport_configuration.timeout if connection.respond_to?(:write_timeout) connection.open_timeout = @transport_configuration.open_timeout ssl_configuration.each do |key, value| connection.send("#{key}=", value) end connection end |
#do_request(endpoint, headers, body) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/sentry/transport/http_transport.rb', line 110 def do_request(endpoint, headers, body) conn.start do |http| request = ::Net::HTTP::Post.new(endpoint, headers) request.body = body http.request(request) end end |
#endpoint ⇒ Object
67 68 69 |
# File 'lib/sentry/transport/http_transport.rb', line 67 def endpoint @dsn.envelope_endpoint end |
#generate_auth_header ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/sentry/transport/http_transport.rb', line 71 def generate_auth_header return nil unless @dsn now = Sentry.utc_now.to_i fields = { "sentry_version" => PROTOCOL_VERSION, "sentry_client" => USER_AGENT, "sentry_timestamp" => now, "sentry_key" => @dsn.public_key } fields["sentry_secret"] = @dsn.secret_key if @dsn.secret_key "Sentry " + fields.map { |key, value| "#{key}=#{value}" }.join(", ") end |
#send_data(data) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/sentry/transport/http_transport.rb', line 31 def send_data(data) encoding = "" if should_compress?(data) data = Zlib.gzip(data) encoding = GZIP_ENCODING end headers = { "Content-Type" => CONTENT_TYPE, "Content-Encoding" => encoding, "User-Agent" => USER_AGENT } auth_header = generate_auth_header headers["X-Sentry-Auth"] = auth_header if auth_header response = do_request(endpoint, headers, data) if response.code.match?(/\A2\d{2}/) handle_rate_limited_response(response) if has_rate_limited_header?(response) elsif response.code == "429" log_debug("the server responded with status 429") handle_rate_limited_response(response) else error_info = "the server responded with status #{response.code}" error_info += "\nbody: #{response.body}" error_info += " Error in headers is: #{response['x-sentry-error']}" if response["x-sentry-error"] raise Sentry::ExternalError, error_info end rescue SocketError, *HTTP_ERRORS => e on_error if respond_to?(:on_error) raise Sentry::ExternalError.new(e&.) end |