elasticsearch-transport 7.10.0 → 7.11.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cec988f9a2a79c9458bc3974d3d52a541cba9b230de23b96df5f74a913de6524
4
- data.tar.gz: 2eb97ff41d033724456132546b642663074dc5859fe2f8a9aa9973dbbf85342d
3
+ metadata.gz: 07e3f02a3b166d00bcee76a0a39731ef5cc2c1aab442d4f6af2b4300a85661d6
4
+ data.tar.gz: 149090dcf60ef7f09637a42e23e33bcc78245872ff470bf064194fad59f2a19c
5
5
  SHA512:
6
- metadata.gz: df0608bf2a72da4d41ce9f7884d63f1279deccd317e1a8379846cee95d556d8f8c91af31049c6d1206b8a28087f4706f655c9a0429beda386d33b82a683dce09
7
- data.tar.gz: 8c37e0c4e02c890241981f42be1a9823d91e9c0c9d010e7193d3a46069448965752495a2e447db15a0f6318d35152c31162a997f3093958cd8e02f623e812cf9
6
+ metadata.gz: a4919e34440ab8a91c2feafb2383e44b518b6b1f122ef59ddf26e35a93c2d1e23ef49f3b7f267eff7a51fd57de671cc66742358b1265ab5211362865ae40127f
7
+ data.tar.gz: b7b9f51e9232c29203cb110bf9e7b1002cffcaac4c583051795e83e590dc4c7a6ea3fd887d0a617f4ed0cb36e0d0e8593ed64c802894990b9c5dbf7eed657773
data/Gemfile CHANGED
@@ -32,7 +32,7 @@ if File.exist? File.expand_path('../../elasticsearch/elasticsearch.gemspec', __F
32
32
  gem 'elasticsearch', path: File.expand_path('../../elasticsearch', __FILE__), require: false
33
33
  end
34
34
 
35
- group :development do
35
+ group :development, :test do
36
36
  gem 'rspec'
37
37
  if defined?(JRUBY_VERSION)
38
38
  gem 'pry-nav'
data/README.md CHANGED
@@ -136,7 +136,7 @@ Please see below for an exception to this when connecting using an Elastic Cloud
136
136
 
137
137
  If you are using [Elastic Cloud](https://www.elastic.co/cloud), you can provide your cloud id to the client.
138
138
  You must supply your username and password separately, and optionally a port. If no port is supplied,
139
- port 9243 will be used.
139
+ port 443 will be used.
140
140
 
141
141
  Note: Do not enable sniffing when using Elastic Cloud. The nodes are behind a load balancer so
142
142
  Elastic Cloud will take care of everything for you.
@@ -187,18 +187,24 @@ Elasticsearch::Client.new(
187
187
 
188
188
  ### Logging
189
189
 
190
- To log requests and responses to standard output with the default logger (an instance of Ruby's {::Logger} class),
191
- set the `log` argument:
190
+ To log requests and responses to standard output with the default logger (an instance of Ruby's {::Logger} class), set the `log` argument to true:
192
191
 
193
192
  ```ruby
194
- Elasticsearch::Client.new log: true
193
+ Elasticsearch::Client.new(log: true)
194
+ ```
195
+
196
+ You can also use [ecs-logging](https://github.com/elastic/ecs-logging-ruby). `ecs-logging` is a set of libraries that allows you to transform your application logs to structured logs that comply with the [Elastic Common Schema (ECS)](https://www.elastic.co/guide/en/ecs/current/ecs-reference.html):
197
+
198
+ ```ruby
199
+ logger = EcsLogging::Logger.new($stdout)
200
+ Elasticsearch::Client.new(logger: logger)
195
201
  ```
196
202
 
197
203
 
198
204
  To trace requests and responses in the _Curl_ format, set the `trace` argument:
199
205
 
200
206
  ```ruby
201
- Elasticsearch::Client.new trace: true
207
+ Elasticsearch::Client.new(trace: true)
202
208
  ```
203
209
 
204
210
  You can customize the default logger or tracer:
@@ -211,7 +217,7 @@ You can customize the default logger or tracer:
211
217
  Or, you can use a custom `::Logger` instance:
212
218
 
213
219
  ```ruby
214
- Elasticsearch::Client.new logger: Logger.new(STDERR)
220
+ Elasticsearch::Client.new(logger: Logger.new(STDERR))
215
221
  ```
216
222
 
217
223
  You can pass the client any conforming logger implementation:
@@ -223,7 +229,7 @@ log = Logging.logger['elasticsearch']
223
229
  log.add_appenders Logging.appenders.stdout
224
230
  log.level = :info
225
231
 
226
- client = Elasticsearch::Client.new logger: log
232
+ client = Elasticsearch::Client.new(logger: log)
227
233
  ```
228
234
 
229
235
  ### Custom HTTP Headers
@@ -16,6 +16,7 @@
16
16
  # under the License.
17
17
 
18
18
  require 'base64'
19
+ require 'elasticsearch/transport/meta_header'
19
20
 
20
21
  module Elasticsearch
21
22
  module Transport
@@ -25,6 +26,7 @@ module Elasticsearch
25
26
  # See {file:README.md README} for usage and code examples.
26
27
  #
27
28
  class Client
29
+ include MetaHeader
28
30
  DEFAULT_TRANSPORT_CLASS = Transport::HTTP::Faraday
29
31
 
30
32
  DEFAULT_LOGGER = lambda do
@@ -49,9 +51,15 @@ module Elasticsearch
49
51
  DEFAULT_HOST = 'localhost:9200'.freeze
50
52
 
51
53
  # The default port to use if connecting using a Cloud ID.
54
+ # Updated from 9243 to 443 in client version 7.10.1
52
55
  #
53
56
  # @since 7.2.0
54
- DEFAULT_CLOUD_PORT = 9243
57
+ DEFAULT_CLOUD_PORT = 443
58
+
59
+ # The default port to use if not otherwise specified.
60
+ #
61
+ # @since 7.2.0
62
+ DEFAULT_PORT = 9200
55
63
 
56
64
  # Returns the transport object.
57
65
  #
@@ -114,8 +122,11 @@ module Elasticsearch
114
122
  #
115
123
  # @option api_key [String, Hash] :api_key Use API Key Authentication, either the base64 encoding of `id` and `api_key`
116
124
  # joined by a colon as a String, or a hash with the `id` and `api_key` values.
117
- # @option opaque_id_prefix [String] :opaque_id_prefix set a prefix for X-Opaque-Id when initializing the client. This
118
- # will be prepended to the id you set before each request if you're using X-Opaque-Id
125
+ # @option opaque_id_prefix [String] :opaque_id_prefix set a prefix for X-Opaque-Id when initializing the client.
126
+ # This will be prepended to the id you set before each request
127
+ # if you're using X-Opaque-Id
128
+ # @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud.
129
+ # (Default: true)
119
130
  #
120
131
  # @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block
121
132
  #
@@ -130,6 +141,7 @@ module Elasticsearch
130
141
  @arguments[:randomize_hosts] ||= false
131
142
  @arguments[:transport_options] ||= {}
132
143
  @arguments[:http] ||= {}
144
+ @arguments[:enable_meta_header] = arguments.fetch(:enable_meta_header) { true }
133
145
  @options[:http] ||= {}
134
146
 
135
147
  set_api_key if (@api_key = @arguments[:api_key])
@@ -152,15 +164,18 @@ module Elasticsearch
152
164
  if @arguments[:transport]
153
165
  @transport = @arguments[:transport]
154
166
  else
155
- transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
156
- if transport_class == Transport::HTTP::Faraday
157
- @transport = transport_class.new(hosts: @seeds, options: @arguments) do |faraday|
158
- faraday.adapter(@arguments[:adapter] || __auto_detect_adapter)
159
- block&.call faraday
160
- end
161
- else
162
- @transport = transport_class.new(hosts: @seeds, options: @arguments)
163
- end
167
+ @transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
168
+ @transport = if @transport_class == Transport::HTTP::Faraday
169
+ @arguments[:adapter] ||= __auto_detect_adapter
170
+ set_meta_header # from include MetaHeader
171
+ @transport_class.new(hosts: @seeds, options: @arguments) do |faraday|
172
+ faraday.adapter(@arguments[:adapter])
173
+ block&.call faraday
174
+ end
175
+ else
176
+ set_meta_header # from include MetaHeader
177
+ @transport_class.new(hosts: @seeds, options: @arguments)
178
+ end
164
179
  end
165
180
  end
166
181
 
@@ -180,13 +195,17 @@ module Elasticsearch
180
195
 
181
196
  def set_api_key
182
197
  @api_key = __encode(@api_key) if @api_key.is_a? Hash
198
+ add_header('Authorization' => "ApiKey #{@api_key}")
199
+ @arguments.delete(:user)
200
+ @arguments.delete(:password)
201
+ end
202
+
203
+ def add_header(header)
183
204
  headers = @arguments[:transport_options]&.[](:headers) || {}
184
- headers.merge!('Authorization' => "ApiKey #{@api_key}")
205
+ headers.merge!(header)
185
206
  @arguments[:transport_options].merge!(
186
207
  headers: headers
187
208
  )
188
- @arguments.delete(:user)
189
- @arguments.delete(:password)
190
209
  end
191
210
 
192
211
  def extract_cloud_creds(arguments)
@@ -243,36 +262,38 @@ module Elasticsearch
243
262
 
244
263
  def __parse_host(host)
245
264
  host_parts = case host
246
- when String
247
- if host =~ /^[a-z]+\:\/\//
248
- # Construct a new `URI::Generic` directly from the array returned by URI::split.
249
- # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
250
- uri = URI::Generic.new(*URI.split(host))
251
-
252
- { :scheme => uri.scheme,
253
- :user => uri.user,
254
- :password => uri.password,
255
- :host => uri.host,
256
- :path => uri.path,
257
- :port => uri.port }
258
- else
259
- host, port = host.split(':')
260
- { :host => host,
261
- :port => port }
262
- end
263
- when URI
264
- { :scheme => host.scheme,
265
- :user => host.user,
266
- :password => host.password,
267
- :host => host.host,
268
- :path => host.path,
269
- :port => host.port }
270
- when Hash
271
- host
272
- else
273
- raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
274
- end
275
-
265
+ when String
266
+ if host =~ /^[a-z]+\:\/\//
267
+ # Construct a new `URI::Generic` directly from the array returned by URI::split.
268
+ # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
269
+ uri = URI::Generic.new(*URI.split(host))
270
+ default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT
271
+ {
272
+ scheme: uri.scheme,
273
+ user: uri.user,
274
+ password: uri.password,
275
+ host: uri.host,
276
+ path: uri.path,
277
+ port: uri.port || default_port
278
+ }
279
+ else
280
+ host, port = host.split(':')
281
+ { host: host, port: port }
282
+ end
283
+ when URI
284
+ {
285
+ scheme: host.scheme,
286
+ user: host.user,
287
+ password: host.password,
288
+ host: host.host,
289
+ path: host.path,
290
+ port: host.port
291
+ }
292
+ when Hash
293
+ host
294
+ else
295
+ raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
296
+ end
276
297
  if @api_key
277
298
  # Remove Basic Auth if using API KEY
278
299
  host_parts.delete(:user)
@@ -0,0 +1,120 @@
1
+ # Licensed to Elasticsearch B.V. under one or more contributor
2
+ # license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright
4
+ # ownership. Elasticsearch B.V. licenses this file to you under
5
+ # the Apache License, Version 2.0 (the "License"); you may
6
+ # not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ require 'base64'
19
+
20
+ module Elasticsearch
21
+ module Transport
22
+
23
+ # Methods for the Elastic meta header used by Cloud.
24
+ # X-Elastic-Client-Meta HTTP header which is used by Elastic Cloud and can be disabled when
25
+ # instantiating the Client with the :enable_meta_header parameter set to `false`.
26
+ #
27
+ module MetaHeader
28
+ def set_meta_header
29
+ return if @arguments[:enable_meta_header] == false
30
+
31
+ service, version = meta_header_service_version
32
+
33
+ meta_headers = {
34
+ service.to_sym => version,
35
+ rb: RUBY_VERSION,
36
+ t: Elasticsearch::Transport::VERSION
37
+ }
38
+ meta_headers.merge!(meta_header_engine) if meta_header_engine
39
+ meta_headers.merge!(meta_header_adapter) if meta_header_adapter
40
+
41
+ add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') })
42
+ end
43
+
44
+ def meta_header_service_version
45
+ if defined?(Elastic::META_HEADER_SERVICE_VERSION)
46
+ Elastic::META_HEADER_SERVICE_VERSION
47
+ elsif defined?(Elasticsearch::VERSION)
48
+ [:es, client_meta_version(Elasticsearch::VERSION)]
49
+ else
50
+ [:es, client_meta_version(Elasticsearch::Transport::VERSION)]
51
+ end
52
+ end
53
+
54
+ # We return the current version if it's a release, but if it's a pre/alpha/beta release we
55
+ # return <VERSION_NUMBER>p
56
+ #
57
+ def client_meta_version(version)
58
+ regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/
59
+ match = version.match(regexp)
60
+ return "#{match[1]}p" if (match[2])
61
+
62
+ version
63
+ end
64
+
65
+ def meta_header_engine
66
+ case RUBY_ENGINE
67
+ when 'ruby'
68
+ {}
69
+ when 'jruby'
70
+ { jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION }
71
+ when 'rbx'
72
+ { rbx: RUBY_VERSION }
73
+ else
74
+ { RUBY_ENGINE.to_sym => RUBY_VERSION }
75
+ end
76
+ end
77
+
78
+ # This function tries to define the version for the Faraday adapter. If it hasn't been loaded
79
+ # by the time we're calling this method, it's going to report the adapter (if we know it) but
80
+ # return 0 as the version. It won't report anything when using a custom adapter we don't
81
+ # identify.
82
+ #
83
+ # Returns a Hash<adapter_alias, version>
84
+ #
85
+ def meta_header_adapter
86
+ if @transport_class == Transport::HTTP::Faraday
87
+ version = '0'
88
+ adapter_version = case @arguments[:adapter]
89
+ when :patron
90
+ version = Patron::VERSION if defined?(::Patron::VERSION)
91
+ {pt: version}
92
+ when :net_http
93
+ version = if defined?(Net::HTTP::VERSION)
94
+ Net::HTTP::VERSION
95
+ elsif defined?(Net::HTTP::HTTPVersion)
96
+ Net::HTTP::HTTPVersion
97
+ end
98
+ {nh: version}
99
+ when :typhoeus
100
+ version = Typhoeus::VERSION if defined?(::Typhoeus::VERSION)
101
+ {ty: version}
102
+ when :httpclient
103
+ version = HTTPClient::VERSION if defined?(HTTPClient::VERSION)
104
+ {hc: version}
105
+ when :net_http_persistent
106
+ version = Net::HTTP::Persistent::VERSION if defined?(Net::HTTP::Persistent::VERSION)
107
+ {np: version}
108
+ else
109
+ {}
110
+ end
111
+ {fd: Faraday::VERSION}.merge(adapter_version)
112
+ elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
113
+ {cl: Curl::CURB_VERSION}
114
+ elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
115
+ {mc: Manticore::VERSION}
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -33,9 +33,17 @@ module Elasticsearch
33
33
  # @return [Response]
34
34
  # @see Transport::Base#perform_request
35
35
  #
36
- def perform_request(method, path, params={}, body=nil, headers=nil, opts={})
36
+ def perform_request(method, path, params = {}, body = nil, headers = nil, opts = {})
37
37
  super do |connection, url|
38
- headers = headers || connection.connection.headers
38
+ headers = if connection.connection.headers
39
+ if !headers.nil?
40
+ connection.connection.headers.merge(headers)
41
+ else
42
+ connection.connection.headers
43
+ end
44
+ else
45
+ headers
46
+ end
39
47
 
40
48
  response = connection.connection.run_request(method.downcase.to_sym,
41
49
  url,
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Elasticsearch
19
19
  module Transport
20
- VERSION = "7.10.0"
20
+ VERSION = '7.11.2'.freeze
21
21
  end
22
22
  end
@@ -246,7 +246,7 @@ describe Elasticsearch::Transport::Client do
246
246
  end
247
247
 
248
248
  let(:client) do
249
- described_class.new(adapter: :patron)
249
+ described_class.new(adapter: :patron, enable_meta_header: false)
250
250
  end
251
251
 
252
252
  it 'uses Faraday with the adapter' do
@@ -260,7 +260,7 @@ describe Elasticsearch::Transport::Client do
260
260
  end
261
261
 
262
262
  let(:client) do
263
- described_class.new(adapter: :typhoeus)
263
+ described_class.new(adapter: :typhoeus, enable_meta_header: false)
264
264
  end
265
265
 
266
266
  it 'uses Faraday with the adapter' do
@@ -274,7 +274,7 @@ describe Elasticsearch::Transport::Client do
274
274
  end
275
275
 
276
276
  let(:client) do
277
- described_class.new('adapter' => :patron)
277
+ described_class.new(adapter: :patron, enable_meta_header: false)
278
278
  end
279
279
 
280
280
  it 'uses Faraday with the adapter' do
@@ -344,24 +344,19 @@ describe Elasticsearch::Transport::Client do
344
344
  expect(hosts[0][:protocol]).to eq('https')
345
345
  expect(hosts[0][:user]).to eq('elastic')
346
346
  expect(hosts[0][:password]).to eq('changeme')
347
- expect(hosts[0][:port]).to eq(9243)
347
+ expect(hosts[0][:port]).to eq(443)
348
348
  end
349
349
 
350
350
  it 'creates the correct full url' do
351
351
  expect(
352
352
  client.transport.__full_url(client.transport.hosts[0])
353
- ).to eq('https://elastic:changeme@abcd.localhost:9243')
353
+ ).to eq('https://elastic:changeme@abcd.localhost:443')
354
354
  end
355
355
 
356
356
  context 'when a port is specified' do
357
357
 
358
358
  let(:client) do
359
- described_class.new(
360
- cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==',
361
- user: 'elastic',
362
- password: 'changeme',
363
- port: 9200
364
- )
359
+ described_class.new(cloud_id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==', user: 'elastic', password: 'changeme', port: 9250)
365
360
  end
366
361
 
367
362
  it 'sets the specified port along with the cloud credentials' do
@@ -369,11 +364,11 @@ describe Elasticsearch::Transport::Client do
369
364
  expect(hosts[0][:protocol]).to eq('https')
370
365
  expect(hosts[0][:user]).to eq('elastic')
371
366
  expect(hosts[0][:password]).to eq('changeme')
372
- expect(hosts[0][:port]).to eq(9200)
367
+ expect(hosts[0][:port]).to eq(9250)
373
368
  end
374
369
 
375
370
  it 'creates the correct full url' do
376
- expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elastic:changeme@abcd.localhost:9200')
371
+ expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://elastic:changeme@abcd.localhost:9250')
377
372
  end
378
373
  end
379
374
 
@@ -396,13 +391,13 @@ describe Elasticsearch::Transport::Client do
396
391
  expect(hosts[0][:protocol]).to eq('https')
397
392
  expect(hosts[0][:user]).to eq('elasticfantastic')
398
393
  expect(hosts[0][:password]).to eq('tobechanged')
399
- expect(hosts[0][:port]).to eq(9243)
394
+ expect(hosts[0][:port]).to eq(443)
400
395
  end
401
396
 
402
397
  it 'creates the correct full url' do
403
398
  expect(
404
399
  client.transport.__full_url(client.transport.hosts[0])
405
- ).to eq('https://elasticfantastic:tobechanged@abcd.localhost:9243')
400
+ ).to eq('https://elasticfantastic:tobechanged@abcd.localhost:443')
406
401
  end
407
402
  end
408
403
 
@@ -424,13 +419,13 @@ describe Elasticsearch::Transport::Client do
424
419
  expect(hosts[0][:protocol]).to eq('https')
425
420
  expect(hosts[0][:user]).to eq('elasticfantastic')
426
421
  expect(hosts[0][:password]).to eq('changeme')
427
- expect(hosts[0][:port]).to eq(9243)
422
+ expect(hosts[0][:port]).to eq(443)
428
423
  end
429
424
 
430
425
  it 'creates the correct full url' do
431
426
  expect(
432
427
  client.transport.__full_url(client.transport.hosts[0])
433
- ).to eq('https://elasticfantastic:changeme@abcd.localhost:9243')
428
+ ).to eq('https://elasticfantastic:changeme@abcd.localhost:443')
434
429
  end
435
430
  end
436
431
 
@@ -482,112 +477,248 @@ describe Elasticsearch::Transport::Client do
482
477
 
483
478
  shared_examples_for 'a client that extracts hosts' do
484
479
 
485
- context 'when the hosts are a String' do
480
+ context 'when the host is a String' do
486
481
 
487
- let(:host) do
488
- 'myhost'
489
- end
482
+ context 'when there is a protocol specified' do
490
483
 
491
- it 'extracts the host' do
492
- expect(hosts[0][:host]).to eq('myhost')
493
- expect(hosts[0][:protocol]).to eq('http')
494
- expect(hosts[0][:port]).to be(9200)
495
- end
484
+ context 'when credentials are specified \'http://USERNAME:PASSWORD@myhost:8080\'' do
496
485
 
497
- context 'when IPv6 format is used' do
486
+ let(:host) do
487
+ 'http://USERNAME:PASSWORD@myhost:8080'
488
+ end
498
489
 
499
- around do |example|
500
- original_setting = Faraday.ignore_env_proxy
501
- Faraday.ignore_env_proxy = true
502
- example.run
503
- Faraday.ignore_env_proxy = original_setting
504
- end
490
+ it 'extracts the credentials' do
491
+ expect(hosts[0][:user]).to eq('USERNAME')
492
+ expect(hosts[0][:password]).to eq('PASSWORD')
493
+ end
505
494
 
506
- let(:host) do
507
- 'https://[2090:db8:85a3:9811::1f]:8080'
508
- end
495
+ it 'extracts the host' do
496
+ expect(hosts[0][:host]).to eq('myhost')
497
+ end
509
498
 
510
- it 'extracts the host' do
511
- expect(hosts[0][:host]).to eq('[2090:db8:85a3:9811::1f]')
512
- expect(hosts[0][:scheme]).to eq('https')
513
- expect(hosts[0][:port]).to be(8080)
499
+ it 'extracts the port' do
500
+ expect(hosts[0][:port]).to be(8080)
501
+ end
514
502
  end
515
503
 
516
- it 'creates the correct full url' do
517
- expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://[2090:db8:85a3:9811::1f]:8080')
518
- end
519
- end
504
+ context 'when there is a trailing slash \'http://myhost/\'' do
520
505
 
521
- context 'when a path is specified' do
506
+ let(:host) do
507
+ 'http://myhost/'
508
+ end
522
509
 
523
- let(:host) do
524
- 'https://myhost:8080/api'
525
- end
510
+ it 'extracts the host' do
511
+ expect(hosts[0][:host]).to eq('myhost')
512
+ expect(hosts[0][:scheme]).to eq('http')
513
+ expect(hosts[0][:path]).to eq('')
514
+ end
526
515
 
527
- it 'extracts the host' do
528
- expect(hosts[0][:host]).to eq('myhost')
529
- expect(hosts[0][:scheme]).to eq('https')
530
- expect(hosts[0][:path]).to eq('/api')
531
- expect(hosts[0][:port]).to be(8080)
516
+ it 'extracts the scheme' do
517
+ expect(hosts[0][:scheme]).to eq('http')
518
+ end
519
+
520
+ it 'extracts the path' do
521
+ expect(hosts[0][:path]).to eq('')
522
+ end
532
523
  end
533
- end
534
524
 
535
- context 'when a scheme is specified' do
525
+ context 'when there is a trailing slash with a path \'http://myhost/foo/bar/\'' do
536
526
 
537
- let(:host) do
538
- 'https://myhost:8080'
539
- end
527
+ let(:host) do
528
+ 'http://myhost/foo/bar/'
529
+ end
540
530
 
541
- it 'extracts the host' do
542
- expect(hosts[0][:host]).to eq('myhost')
543
- expect(hosts[0][:scheme]).to eq('https')
544
- expect(hosts[0][:port]).to be(8080)
531
+ it 'extracts the host' do
532
+ expect(hosts[0][:host]).to eq('myhost')
533
+ expect(hosts[0][:scheme]).to eq('http')
534
+ expect(hosts[0][:path]).to eq('/foo/bar')
535
+ end
545
536
  end
546
- end
547
537
 
548
- context 'when credentials are specified' do
538
+ context 'when the protocol is http' do
549
539
 
550
- let(:host) do
551
- 'http://USERNAME:PASSWORD@myhost:8080'
552
- end
540
+ context 'when there is no port specified \'http://myhost\'' do
553
541
 
554
- it 'extracts the host' do
555
- expect(hosts[0][:host]).to eq('myhost')
556
- expect(hosts[0][:scheme]).to eq('http')
557
- expect(hosts[0][:user]).to eq('USERNAME')
558
- expect(hosts[0][:password]).to eq('PASSWORD')
559
- expect(hosts[0][:port]).to be(8080)
560
- end
561
- end
542
+ let(:host) do
543
+ 'http://myhost'
544
+ end
562
545
 
563
- context 'when there is a trailing slash' do
546
+ it 'extracts the host' do
547
+ expect(hosts[0][:host]).to eq('myhost')
548
+ end
564
549
 
565
- let(:host) do
566
- 'http://myhost/'
550
+ it 'extracts the protocol' do
551
+ expect(hosts[0][:protocol]).to eq('http')
552
+ end
553
+
554
+ it 'defaults to port 9200' do
555
+ expect(hosts[0][:port]).to be(9200)
556
+ end
557
+ end
558
+
559
+ context 'when there is a port specified \'http://myhost:7101\'' do
560
+
561
+ let(:host) do
562
+ 'http://myhost:7101'
563
+ end
564
+
565
+ it 'extracts the host' do
566
+ expect(hosts[0][:host]).to eq('myhost')
567
+ end
568
+
569
+ it 'extracts the protocol' do
570
+ expect(hosts[0][:protocol]).to eq('http')
571
+ end
572
+
573
+ it 'extracts the port' do
574
+ expect(hosts[0][:port]).to be(7101)
575
+ end
576
+
577
+ context 'when there is a path specified \'http://myhost:7101/api\'' do
578
+
579
+ let(:host) do
580
+ 'http://myhost:7101/api'
581
+ end
582
+
583
+ it 'sets the path' do
584
+ expect(hosts[0][:host]).to eq('myhost')
585
+ expect(hosts[0][:protocol]).to eq('http')
586
+ expect(hosts[0][:path]).to eq('/api')
587
+ expect(hosts[0][:port]).to be(7101)
588
+ end
589
+
590
+ it 'extracts the host' do
591
+ expect(hosts[0][:host]).to eq('myhost')
592
+ end
593
+
594
+ it 'extracts the protocol' do
595
+ expect(hosts[0][:protocol]).to eq('http')
596
+ end
597
+
598
+ it 'extracts the port' do
599
+ expect(hosts[0][:port]).to be(7101)
600
+ end
601
+
602
+ it 'extracts the path' do
603
+ expect(hosts[0][:path]).to eq('/api')
604
+ end
605
+ end
606
+ end
567
607
  end
568
608
 
569
- it 'extracts the host' do
570
- expect(hosts[0][:host]).to eq('myhost')
571
- expect(hosts[0][:scheme]).to eq('http')
572
- expect(hosts[0][:path]).to eq('')
609
+ context 'when the protocol is https' do
610
+
611
+ context 'when there is no port specified \'https://myhost\'' do
612
+
613
+ let(:host) do
614
+ 'https://myhost'
615
+ end
616
+
617
+ it 'extracts the host' do
618
+ expect(hosts[0][:host]).to eq('myhost')
619
+ end
620
+
621
+ it 'extracts the protocol' do
622
+ expect(hosts[0][:protocol]).to eq('https')
623
+ end
624
+
625
+ it 'defaults to port 443' do
626
+ expect(hosts[0][:port]).to be(443)
627
+ end
628
+ end
629
+
630
+ context 'when there is a port specified \'https://myhost:7101\'' do
631
+
632
+ let(:host) do
633
+ 'https://myhost:7101'
634
+ end
635
+
636
+ it 'extracts the host' do
637
+ expect(hosts[0][:host]).to eq('myhost')
638
+ end
639
+
640
+ it 'extracts the protocol' do
641
+ expect(hosts[0][:protocol]).to eq('https')
642
+ end
643
+
644
+ it 'extracts the port' do
645
+ expect(hosts[0][:port]).to be(7101)
646
+ end
647
+
648
+ context 'when there is a path specified \'https://myhost:7101/api\'' do
649
+
650
+ let(:host) do
651
+ 'https://myhost:7101/api'
652
+ end
653
+
654
+ it 'extracts the host' do
655
+ expect(hosts[0][:host]).to eq('myhost')
656
+ end
657
+
658
+ it 'extracts the protocol' do
659
+ expect(hosts[0][:protocol]).to eq('https')
660
+ end
661
+
662
+ it 'extracts the port' do
663
+ expect(hosts[0][:port]).to be(7101)
664
+ end
665
+
666
+ it 'extracts the path' do
667
+ expect(hosts[0][:path]).to eq('/api')
668
+ end
669
+ end
670
+ end
671
+
672
+ context 'when IPv6 format is used' do
673
+
674
+ around do |example|
675
+ original_setting = Faraday.ignore_env_proxy
676
+ Faraday.ignore_env_proxy = true
677
+ example.run
678
+ Faraday.ignore_env_proxy = original_setting
679
+ end
680
+
681
+ let(:host) do
682
+ 'https://[2090:db8:85a3:9811::1f]:8080'
683
+ end
684
+
685
+ it 'extracts the host' do
686
+ expect(hosts[0][:host]).to eq('[2090:db8:85a3:9811::1f]')
687
+ end
688
+
689
+ it 'extracts the protocol' do
690
+ expect(hosts[0][:protocol]).to eq('https')
691
+ end
692
+
693
+ it 'extracts the port' do
694
+ expect(hosts[0][:port]).to be(8080)
695
+ end
696
+
697
+ it 'creates the correct full url' do
698
+ expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://[2090:db8:85a3:9811::1f]:8080')
699
+ end
700
+ end
573
701
  end
574
702
  end
575
703
 
576
- context 'when there is a trailing slash with a path' do
704
+ context 'when no protocol is specified \'myhost\'' do
577
705
 
578
706
  let(:host) do
579
- 'http://myhost/foo/bar/'
707
+ 'myhost'
580
708
  end
581
709
 
582
- it 'extracts the host' do
710
+ it 'defaults to http' do
583
711
  expect(hosts[0][:host]).to eq('myhost')
584
- expect(hosts[0][:scheme]).to eq('http')
585
- expect(hosts[0][:path]).to eq('/foo/bar')
712
+ expect(hosts[0][:protocol]).to eq('http')
713
+ end
714
+
715
+ it 'uses port 9200' do
716
+ expect(hosts[0][:port]).to be(9200)
586
717
  end
587
718
  end
588
719
  end
589
720
 
590
- context 'when the hosts are a Hash' do
721
+ context 'when the host is a Hash' do
591
722
 
592
723
  let(:host) do
593
724
  { :host => 'myhost', :scheme => 'https' }
@@ -595,7 +726,13 @@ describe Elasticsearch::Transport::Client do
595
726
 
596
727
  it 'extracts the host' do
597
728
  expect(hosts[0][:host]).to eq('myhost')
598
- expect(hosts[0][:scheme]).to eq('https')
729
+ end
730
+
731
+ it 'extracts the protocol' do
732
+ expect(hosts[0][:protocol]).to eq('https')
733
+ end
734
+
735
+ it 'extracts the port' do
599
736
  expect(hosts[0][:port]).to be(9200)
600
737
  end
601
738
 
@@ -654,7 +791,13 @@ describe Elasticsearch::Transport::Client do
654
791
 
655
792
  it 'extracts the host' do
656
793
  expect(hosts[0][:host]).to eq('myhost')
794
+ end
795
+
796
+ it 'extracts the protocol' do
657
797
  expect(hosts[0][:scheme]).to eq('https')
798
+ end
799
+
800
+ it 'converts the port to an integer' do
658
801
  expect(hosts[0][:port]).to be(443)
659
802
  end
660
803
  end
@@ -667,7 +810,13 @@ describe Elasticsearch::Transport::Client do
667
810
 
668
811
  it 'extracts the host' do
669
812
  expect(hosts[0][:host]).to eq('myhost')
813
+ end
814
+
815
+ it 'extracts the protocol' do
670
816
  expect(hosts[0][:scheme]).to eq('https')
817
+ end
818
+
819
+ it 'extracts port as an integer' do
671
820
  expect(hosts[0][:port]).to be(443)
672
821
  end
673
822
  end
@@ -681,7 +830,13 @@ describe Elasticsearch::Transport::Client do
681
830
 
682
831
  it 'extracts the host' do
683
832
  expect(hosts[0][:host]).to eq('myhost')
833
+ end
834
+
835
+ it 'extracts the protocol' do
684
836
  expect(hosts[0][:scheme]).to eq('https')
837
+ end
838
+
839
+ it 'converts the port to an integer' do
685
840
  expect(hosts[0][:port]).to be(9200)
686
841
  end
687
842
 
@@ -693,7 +848,13 @@ describe Elasticsearch::Transport::Client do
693
848
 
694
849
  it 'extracts the host' do
695
850
  expect(hosts[0][:host]).to eq('myhost')
851
+ end
852
+
853
+ it 'extracts the protocol' do
696
854
  expect(hosts[0][:scheme]).to eq('https')
855
+ end
856
+
857
+ it 'converts the port to an integer' do
697
858
  expect(hosts[0][:port]).to be(443)
698
859
  end
699
860
  end
@@ -706,7 +867,13 @@ describe Elasticsearch::Transport::Client do
706
867
 
707
868
  it 'extracts the host' do
708
869
  expect(hosts[0][:host]).to eq('myhost')
870
+ end
871
+
872
+ it 'extracts the protocol' do
709
873
  expect(hosts[0][:scheme]).to eq('https')
874
+ end
875
+
876
+ it 'extracts port as an integer' do
710
877
  expect(hosts[0][:port]).to be(443)
711
878
  end
712
879
  end
@@ -722,7 +889,13 @@ describe Elasticsearch::Transport::Client do
722
889
 
723
890
  it 'extracts the host' do
724
891
  expect(hosts[0][:host]).to eq('myhost')
892
+ end
893
+
894
+ it 'extracts the protocol' do
725
895
  expect(hosts[0][:protocol]).to eq('http')
896
+ end
897
+
898
+ it 'defaults to port 9200' do
726
899
  expect(hosts[0][:port]).to be(9200)
727
900
  end
728
901
  end
@@ -735,20 +908,13 @@ describe Elasticsearch::Transport::Client do
735
908
 
736
909
  it 'extracts the host' do
737
910
  expect(hosts[0][:host]).to eq('myhost')
738
- expect(hosts[0][:protocol]).to eq('http')
739
- expect(hosts[0][:port]).to be(9200)
740
911
  end
741
- end
742
-
743
- context 'when there is one host with a protocol and no port' do
744
912
 
745
- let(:host) do
746
- ['http://myhost']
913
+ it 'extracts the protocol' do
914
+ expect(hosts[0][:scheme]).to eq('http')
747
915
  end
748
916
 
749
- it 'extracts the host' do
750
- expect(hosts[0][:host]).to eq('myhost')
751
- expect(hosts[0][:protocol]).to eq('http')
917
+ it 'defaults to port 9200' do
752
918
  expect(hosts[0][:port]).to be(9200)
753
919
  end
754
920
  end
@@ -773,7 +939,7 @@ describe Elasticsearch::Transport::Client do
773
939
  end
774
940
  end
775
941
 
776
- context 'when there is one host with a scheme, protocol and no port' do
942
+ context 'when there is one host with a protocol and no port' do
777
943
 
778
944
  let(:host) do
779
945
  ['https://myhost']
@@ -781,12 +947,18 @@ describe Elasticsearch::Transport::Client do
781
947
 
782
948
  it 'extracts the host' do
783
949
  expect(hosts[0][:host]).to eq('myhost')
784
- expect(hosts[0][:protocol]).to eq('https')
785
- expect(hosts[0][:port]).to be(9200)
950
+ end
951
+
952
+ it 'extracts the protocol' do
953
+ expect(hosts[0][:scheme]).to eq('https')
954
+ end
955
+
956
+ it 'defaults to port 443' do
957
+ expect(hosts[0][:port]).to be(443)
786
958
  end
787
959
  end
788
960
 
789
- context 'when there is one host with a scheme, protocol, path, and no port' do
961
+ context 'when there is one host with a protocol, path, and no port' do
790
962
 
791
963
  let(:host) do
792
964
  ['http://myhost/foo/bar']
@@ -794,9 +966,18 @@ describe Elasticsearch::Transport::Client do
794
966
 
795
967
  it 'extracts the host' do
796
968
  expect(hosts[0][:host]).to eq('myhost')
797
- expect(hosts[0][:protocol]).to eq('http')
969
+ end
970
+
971
+ it 'extracts the protocol' do
972
+ expect(hosts[0][:scheme]).to eq('http')
973
+ end
974
+
975
+ it 'defaults to port 9200' do
798
976
  expect(hosts[0][:port]).to be(9200)
799
- expect(hosts[0][:path]).to eq("/foo/bar")
977
+ end
978
+
979
+ it 'extracts the path' do
980
+ expect(hosts[0][:path]).to eq('/foo/bar')
800
981
  end
801
982
  end
802
983
 
@@ -806,7 +987,7 @@ describe Elasticsearch::Transport::Client do
806
987
  ['host1', 'host2']
807
988
  end
808
989
 
809
- it 'extracts the host' do
990
+ it 'extracts the hosts' do
810
991
  expect(hosts[0][:host]).to eq('host1')
811
992
  expect(hosts[0][:protocol]).to eq('http')
812
993
  expect(hosts[0][:port]).to be(9200)
@@ -822,7 +1003,7 @@ describe Elasticsearch::Transport::Client do
822
1003
  ['host1:1000', 'host2:2000']
823
1004
  end
824
1005
 
825
- it 'extracts the host' do
1006
+ it 'extracts the hosts' do
826
1007
  expect(hosts[0][:host]).to eq('host1')
827
1008
  expect(hosts[0][:protocol]).to eq('http')
828
1009
  expect(hosts[0][:port]).to be(1000)
@@ -1242,7 +1423,7 @@ describe Elasticsearch::Transport::Client do
1242
1423
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1243
1424
  expect { client.search(opaque_id: 'opaque_id') }.not_to raise_error
1244
1425
  expect(client).to have_received(:perform_request)
1245
- .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1426
+ .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1246
1427
  end
1247
1428
  end
1248
1429
  end
@@ -1281,7 +1462,28 @@ describe Elasticsearch::Transport::Client do
1281
1462
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1282
1463
  expect { client.search(headers: headers) }.not_to raise_error
1283
1464
  expect(client).to have_received(:perform_request)
1284
- .with('GET', '_search', {}, nil, headers)
1465
+ .with('GET', '_search', {}, nil, headers)
1466
+ end
1467
+ end
1468
+
1469
+ context 'when a header is set on an endpoint request and on initialization' do
1470
+ let!(:client) do
1471
+ described_class.new(
1472
+ host: hosts,
1473
+ transport_options: { headers: instance_headers }
1474
+ )
1475
+ end
1476
+ let(:instance_headers) { { set_in_instantiation: 'header value' } }
1477
+ let(:param_headers) {{'user-agent' => 'My Ruby Tests', 'set-on-method-call' => 'header value'}}
1478
+
1479
+ it 'performs the request with the header' do
1480
+ expected_headers = client.transport.connections.connections.first.connection.headers.merge(param_headers)
1481
+
1482
+ expect_any_instance_of(Faraday::Connection)
1483
+ .to receive(:run_request)
1484
+ .with(:get, "http://#{hosts[0]}/_search", nil, expected_headers) { OpenStruct.new(body: '')}
1485
+
1486
+ client.search(headers: param_headers)
1285
1487
  end
1286
1488
  end
1287
1489
  end
@@ -1503,7 +1705,7 @@ describe Elasticsearch::Transport::Client do
1503
1705
  context 'when using the HTTPClient adapter' do
1504
1706
 
1505
1707
  let(:client) do
1506
- described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient)
1708
+ described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :httpclient, enable_meta_header: false)
1507
1709
  end
1508
1710
 
1509
1711
  it 'compresses the request and decompresses the response' do