-
Notifications
You must be signed in to change notification settings - Fork 18
/
curb.rb
124 lines (109 loc) · 4.53 KB
/
curb.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Licensed to Elasticsearch B.V. under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
module Elastic
module Transport
module Transport
module HTTP
# Alternative HTTP transport implementation, using the [_Curb_](https://rubygems.org/gems/curb) client.
#
# @see Transport::Base
#
class Curb
include Base
# Performs the request by invoking {Transport::Base#perform_request} with a block.
#
# @return [Response]
# @see Transport::Base#perform_request
#
def perform_request(method, path, params={}, body=nil, headers=nil, opts={})
super do |connection, url|
capture_otel_span_attributes(connection, url)
connection.connection.url = connection.full_url(path, params)
body = body ? __convert_to_json(body) : nil
body, headers = compress_request(body, headers)
case method
when 'HEAD'
connection.connection.set :nobody, true
when 'GET', 'POST', 'PUT', 'DELETE'
connection.connection.set :nobody, false
connection.connection.put_data = body if body
if headers
if connection.connection.headers
connection.connection.headers.merge!(headers)
else
connection.connection.headers = headers
end
end
else raise ArgumentError, "Unsupported HTTP method: #{method}"
end
connection.connection.http(method.to_sym)
header_string = connection.connection.header_str.to_s
_response_status, *response_headers = header_string.split(/[\r\n]+/).map(&:strip)
response_headers = Hash[response_headers.flat_map { |s| s.scan(/^(\S+): (.+)/) }].transform_keys(&:downcase)
Response.new(
connection.connection.response_code,
decompress_response(connection.connection.body_str),
response_headers
)
end
end
# Builds and returns a connection
#
# @return [Connections::Connection]
#
def __build_connection(host, options={}, block=nil)
client = ::Curl::Easy.new
apply_headers(client, options)
client.url = __full_url(host)
if host[:user]
client.http_auth_types = host[:auth_type] || :basic
client.username = host[:user]
client.password = host[:password]
end
client.instance_eval(&block) if block
Connections::Connection.new :host => host, :connection => client
end
# Returns an array of implementation specific connection errors.
#
# @return [Array]
#
def host_unreachable_exceptions
[
::Curl::Err::HostResolutionError,
::Curl::Err::ConnectionFailedError,
::Curl::Err::GotNothingError,
::Curl::Err::RecvError,
::Curl::Err::SendError,
::Curl::Err::TimeoutError
]
end
private
def user_agent_header(client)
@user_agent ||= begin
meta = ["RUBY_VERSION: #{RUBY_VERSION}"]
if RbConfig::CONFIG && RbConfig::CONFIG['host_os']
meta << "#{RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase} #{RbConfig::CONFIG['target_cpu']}"
end
meta << "Curb #{Curl::CURB_VERSION}"
"elastic-transport-ruby/#{VERSION} (#{meta.join('; ')})"
end
end
end
end
end
end
end