elasticsearch-transport 7.10.0.pre → 7.11.1

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: 64ed0d4e52c93d1bfaabaef470e71308ac9961da744584f770283f605131e3ac
4
- data.tar.gz: 40b0baa58407ef49ac9fac314fbd9f84df3c8408d7312132ebe8f19cb1f5e35c
3
+ metadata.gz: a61db52575ad4a8669cbef5e60e6f90607f82155206c85e9e473835dfa35e0e5
4
+ data.tar.gz: e8d2f1899f4ebf17cfafdfee98174f86ba52633f04d8fadd30ec9b4d31457546
5
5
  SHA512:
6
- metadata.gz: 24eefe245bb7fc61431b6798d0898bbadc4c0fafbefa6303b61336e4673df8e37f6ae71e0dc107ea0c446821a0d8138ebad16380a13b8dcb2ce5ee3c762acd8f
7
- data.tar.gz: 8b790e93528ae4c3db68a7f63272f2cf0eefc3e9a8b66d2e2d1b8b8bd6dea67cdb180789e2df824cdc50eb90c8ef669fb7968f370c13d34d27dc2f3329ca5e53
6
+ metadata.gz: 0ca54a9d0f096d1f8675ea7ef4d84da517f34ffeea31c9ce72f3c4a9257cfab33d6548582490ff7f87708a0ff3bc25a29c907274870d2ea22df34d7585c6d59e
7
+ data.tar.gz: 854a17c7995ceede84fa87f73ccb7fafd8d57a8ff400429e8877258bd00e7cadbc69562400af8d682cb195b51599867bfce2fc84db151d3bff45c846844b188b
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'
File without changes
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
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
40
40
  s.require_paths = ['lib']
41
41
 
42
- s.extra_rdoc_files = [ 'README.md', 'LICENSE.txt' ]
42
+ s.extra_rdoc_files = [ 'README.md', 'LICENSE' ]
43
43
  s.rdoc_options = [ '--charset=UTF-8' ]
44
44
 
45
45
  s.required_ruby_version = '>= 2.4'
@@ -49,9 +49,15 @@ module Elasticsearch
49
49
  DEFAULT_HOST = 'localhost:9200'.freeze
50
50
 
51
51
  # The default port to use if connecting using a Cloud ID.
52
+ # Updated from 9243 to 443 in client version 7.10.1
52
53
  #
53
54
  # @since 7.2.0
54
- DEFAULT_CLOUD_PORT = 9243
55
+ DEFAULT_CLOUD_PORT = 443
56
+
57
+ # The default port to use if not otherwise specified.
58
+ #
59
+ # @since 7.2.0
60
+ DEFAULT_PORT = 9200
55
61
 
56
62
  # Returns the transport object.
57
63
  #
@@ -114,8 +120,11 @@ module Elasticsearch
114
120
  #
115
121
  # @option api_key [String, Hash] :api_key Use API Key Authentication, either the base64 encoding of `id` and `api_key`
116
122
  # 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
123
+ # @option opaque_id_prefix [String] :opaque_id_prefix set a prefix for X-Opaque-Id when initializing the client.
124
+ # This will be prepended to the id you set before each request
125
+ # if you're using X-Opaque-Id
126
+ # @option enable_meta_header [Boolean] :enable_meta_header Enable sending the meta data header to Cloud.
127
+ # (Default: true)
119
128
  #
120
129
  # @yield [faraday] Access and configure the `Faraday::Connection` instance directly with a block
121
130
  #
@@ -130,6 +139,7 @@ module Elasticsearch
130
139
  @arguments[:randomize_hosts] ||= false
131
140
  @arguments[:transport_options] ||= {}
132
141
  @arguments[:http] ||= {}
142
+ @arguments[:enable_meta_header] = arguments.fetch(:enable_meta_header) { true }
133
143
  @options[:http] ||= {}
134
144
 
135
145
  set_api_key if (@api_key = @arguments[:api_key])
@@ -152,15 +162,18 @@ module Elasticsearch
152
162
  if @arguments[:transport]
153
163
  @transport = @arguments[:transport]
154
164
  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
165
+ @transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
166
+ @transport = if @transport_class == Transport::HTTP::Faraday
167
+ @arguments[:adapter] ||= __auto_detect_adapter
168
+ set_meta_header
169
+ @transport_class.new(hosts: @seeds, options: @arguments) do |faraday|
170
+ faraday.adapter(@arguments[:adapter])
171
+ block&.call faraday
172
+ end
173
+ else
174
+ set_meta_header
175
+ @transport_class.new(hosts: @seeds, options: @arguments)
176
+ end
164
177
  end
165
178
  end
166
179
 
@@ -180,27 +193,111 @@ module Elasticsearch
180
193
 
181
194
  def set_api_key
182
195
  @api_key = __encode(@api_key) if @api_key.is_a? Hash
196
+ add_header('Authorization' => "ApiKey #{@api_key}")
197
+ @arguments.delete(:user)
198
+ @arguments.delete(:password)
199
+ end
200
+
201
+ def add_header(header)
183
202
  headers = @arguments[:transport_options]&.[](:headers) || {}
184
- headers.merge!('Authorization' => "ApiKey #{@api_key}")
203
+ headers.merge!(header)
185
204
  @arguments[:transport_options].merge!(
186
205
  headers: headers
187
206
  )
188
- @arguments.delete(:user)
189
- @arguments.delete(:password)
207
+ end
208
+
209
+ def set_meta_header
210
+ return if @arguments[:enable_meta_header] == false
211
+
212
+ service, version = meta_header_service_version
213
+
214
+ meta_headers = {
215
+ service.to_sym => version,
216
+ rb: RUBY_VERSION,
217
+ t: Elasticsearch::Transport::VERSION
218
+ }
219
+ meta_headers.merge!(meta_header_engine) if meta_header_engine
220
+ meta_headers.merge!(meta_header_adapter) if meta_header_adapter
221
+
222
+ add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') })
223
+ end
224
+
225
+ def meta_header_service_version
226
+ if defined?(Elastic::META_HEADER_SERVICE_VERSION)
227
+ Elastic::META_HEADER_SERVICE_VERSION
228
+ elsif defined?(Elasticsearch::VERSION)
229
+ [:es, client_meta_version(Elasticsearch::VERSION)]
230
+ else
231
+ [:es, client_meta_version(Elasticsearch::Transport::VERSION)]
232
+ end
233
+ end
234
+
235
+ def client_meta_version(version)
236
+ regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/
237
+ match = version.match(regexp)
238
+ return "#{match[1]}p" if (match[2])
239
+
240
+ version
241
+ end
242
+
243
+ def meta_header_engine
244
+ case RUBY_ENGINE
245
+ when 'ruby'
246
+ {}
247
+ when 'jruby'
248
+ { jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION }
249
+ when 'rbx'
250
+ { rbx: RUBY_VERSION }
251
+ else
252
+ { RUBY_ENGINE.to_sym => RUBY_VERSION }
253
+ end
254
+ end
255
+
256
+ def meta_header_adapter
257
+ if @transport_class == Transport::HTTP::Faraday
258
+ {fd: Faraday::VERSION}.merge(
259
+ case @arguments[:adapter]
260
+ when :patron
261
+ {pt: Patron::VERSION}
262
+ when :net_http
263
+ {nh: defined?(Net::HTTP::VERSION) ? Net::HTTP::VERSION : Net::HTTP::HTTPVersion}
264
+ when :typhoeus
265
+ {ty: Typhoeus::VERSION}
266
+ when :httpclient
267
+ {hc: HTTPClient::VERSION}
268
+ when :net_http_persistent
269
+ {np: Net::HTTP::Persistent::VERSION}
270
+ else
271
+ {}
272
+ end
273
+ )
274
+ elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
275
+ {cl: Curl::CURB_VERSION}
276
+ elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
277
+ {mc: Manticore::VERSION}
278
+ end
190
279
  end
191
280
 
192
281
  def extract_cloud_creds(arguments)
193
- return unless arguments[:cloud_id]
282
+ return unless arguments[:cloud_id] && !arguments[:cloud_id].empty?
194
283
 
195
284
  name = arguments[:cloud_id].split(':')[0]
196
285
  cloud_url, elasticsearch_instance = Base64.decode64(arguments[:cloud_id].gsub("#{name}:", '')).split('$')
286
+
287
+ if cloud_url.include?(':')
288
+ url, port = cloud_url.split(':')
289
+ host = "#{elasticsearch_instance}.#{url}"
290
+ else
291
+ host = "#{elasticsearch_instance}.#{cloud_url}"
292
+ port = arguments[:port] || DEFAULT_CLOUD_PORT
293
+ end
197
294
  [
198
295
  {
199
296
  scheme: 'https',
200
297
  user: arguments[:user],
201
298
  password: arguments[:password],
202
- host: "#{elasticsearch_instance}.#{cloud_url}",
203
- port: arguments[:port] || DEFAULT_CLOUD_PORT
299
+ host: host,
300
+ port: port.to_i
204
301
  }
205
302
  ]
206
303
  end
@@ -235,36 +332,38 @@ module Elasticsearch
235
332
 
236
333
  def __parse_host(host)
237
334
  host_parts = case host
238
- when String
239
- if host =~ /^[a-z]+\:\/\//
240
- # Construct a new `URI::Generic` directly from the array returned by URI::split.
241
- # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
242
- uri = URI::Generic.new(*URI.split(host))
243
-
244
- { :scheme => uri.scheme,
245
- :user => uri.user,
246
- :password => uri.password,
247
- :host => uri.host,
248
- :path => uri.path,
249
- :port => uri.port }
250
- else
251
- host, port = host.split(':')
252
- { :host => host,
253
- :port => port }
254
- end
255
- when URI
256
- { :scheme => host.scheme,
257
- :user => host.user,
258
- :password => host.password,
259
- :host => host.host,
260
- :path => host.path,
261
- :port => host.port }
262
- when Hash
263
- host
264
- else
265
- raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
266
- end
267
-
335
+ when String
336
+ if host =~ /^[a-z]+\:\/\//
337
+ # Construct a new `URI::Generic` directly from the array returned by URI::split.
338
+ # This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
339
+ uri = URI::Generic.new(*URI.split(host))
340
+ default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT
341
+ {
342
+ scheme: uri.scheme,
343
+ user: uri.user,
344
+ password: uri.password,
345
+ host: uri.host,
346
+ path: uri.path,
347
+ port: uri.port || default_port
348
+ }
349
+ else
350
+ host, port = host.split(':')
351
+ { host: host, port: port }
352
+ end
353
+ when URI
354
+ {
355
+ scheme: host.scheme,
356
+ user: host.user,
357
+ password: host.password,
358
+ host: host.host,
359
+ path: host.path,
360
+ port: host.port
361
+ }
362
+ when Hash
363
+ host
364
+ else
365
+ raise ArgumentError, "Please pass host as a String, URI or Hash -- #{host.class} given."
366
+ end
268
367
  if @api_key
269
368
  # Remove Basic Auth if using API KEY
270
369
  host_parts.delete(:user)
@@ -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.pre"
20
+ VERSION = '7.11.1'.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,125 +419,306 @@ 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
- end
437
431
 
438
- shared_examples_for 'a client that extracts hosts' do
432
+ context 'when the cloud host provides a port' do
433
+ let(:client) do
434
+ described_class.new(
435
+ cloud_id: 'name:ZWxhc3RpY19zZXJ2ZXI6OTI0MyRlbGFzdGljX2lk',
436
+ user: 'elastic',
437
+ password: 'changeme'
438
+ )
439
+ end
439
440
 
440
- context 'when the hosts are a String' do
441
+ let(:hosts) do
442
+ client.transport.hosts
443
+ end
441
444
 
442
- let(:host) do
443
- 'myhost'
445
+ it 'creates the correct full url' do
446
+ expect(hosts[0][:host]).to eq('elastic_id.elastic_server')
447
+ expect(hosts[0][:protocol]).to eq('https')
448
+ expect(hosts[0][:user]).to eq('elastic')
449
+ expect(hosts[0][:password]).to eq('changeme')
450
+ expect(hosts[0][:port]).to eq(9243)
444
451
  end
452
+ end
445
453
 
446
- it 'extracts the host' do
447
- expect(hosts[0][:host]).to eq('myhost')
448
- expect(hosts[0][:protocol]).to eq('http')
449
- expect(hosts[0][:port]).to be(9200)
454
+ context 'when the cloud host provides a port and the port is also specified' do
455
+ let(:client) do
456
+ described_class.new(
457
+ cloud_id: 'name:ZWxhc3RpY19zZXJ2ZXI6OTI0MyRlbGFzdGljX2lk',
458
+ user: 'elastic',
459
+ password: 'changeme',
460
+ port: 9200
461
+ )
450
462
  end
451
463
 
452
- context 'when IPv6 format is used' do
464
+ let(:hosts) do
465
+ client.transport.hosts
466
+ end
453
467
 
454
- around do |example|
455
- original_setting = Faraday.ignore_env_proxy
456
- Faraday.ignore_env_proxy = true
457
- example.run
458
- Faraday.ignore_env_proxy = original_setting
459
- end
468
+ it 'creates the correct full url' do
469
+ expect(hosts[0][:host]).to eq('elastic_id.elastic_server')
470
+ expect(hosts[0][:protocol]).to eq('https')
471
+ expect(hosts[0][:user]).to eq('elastic')
472
+ expect(hosts[0][:password]).to eq('changeme')
473
+ expect(hosts[0][:port]).to eq(9243)
474
+ end
475
+ end
476
+ end
460
477
 
461
- let(:host) do
462
- 'https://[2090:db8:85a3:9811::1f]:8080'
463
- end
478
+ shared_examples_for 'a client that extracts hosts' do
464
479
 
465
- it 'extracts the host' do
466
- expect(hosts[0][:host]).to eq('[2090:db8:85a3:9811::1f]')
467
- expect(hosts[0][:scheme]).to eq('https')
468
- expect(hosts[0][:port]).to be(8080)
469
- end
480
+ context 'when the host is a String' do
470
481
 
471
- it 'creates the correct full url' do
472
- expect(client.transport.__full_url(client.transport.hosts[0])).to eq('https://[2090:db8:85a3:9811::1f]:8080')
473
- end
474
- end
482
+ context 'when there is a protocol specified' do
475
483
 
476
- context 'when a path is specified' do
484
+ context 'when credentials are specified \'http://USERNAME:PASSWORD@myhost:8080\'' do
477
485
 
478
- let(:host) do
479
- 'https://myhost:8080/api'
480
- end
486
+ let(:host) do
487
+ 'http://USERNAME:PASSWORD@myhost:8080'
488
+ end
481
489
 
482
- it 'extracts the host' do
483
- expect(hosts[0][:host]).to eq('myhost')
484
- expect(hosts[0][:scheme]).to eq('https')
485
- expect(hosts[0][:path]).to eq('/api')
486
- expect(hosts[0][:port]).to be(8080)
487
- end
488
- 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
489
494
 
490
- context 'when a scheme is specified' do
495
+ it 'extracts the host' do
496
+ expect(hosts[0][:host]).to eq('myhost')
497
+ end
491
498
 
492
- let(:host) do
493
- 'https://myhost:8080'
499
+ it 'extracts the port' do
500
+ expect(hosts[0][:port]).to be(8080)
501
+ end
494
502
  end
495
503
 
496
- it 'extracts the host' do
497
- expect(hosts[0][:host]).to eq('myhost')
498
- expect(hosts[0][:scheme]).to eq('https')
499
- expect(hosts[0][:port]).to be(8080)
500
- end
501
- end
504
+ context 'when there is a trailing slash \'http://myhost/\'' do
502
505
 
503
- context 'when credentials are specified' do
506
+ let(:host) do
507
+ 'http://myhost/'
508
+ end
504
509
 
505
- let(:host) do
506
- 'http://USERNAME:PASSWORD@myhost:8080'
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
515
+
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
507
523
  end
508
524
 
509
- it 'extracts the host' do
510
- expect(hosts[0][:host]).to eq('myhost')
511
- expect(hosts[0][:scheme]).to eq('http')
512
- expect(hosts[0][:user]).to eq('USERNAME')
513
- expect(hosts[0][:password]).to eq('PASSWORD')
514
- expect(hosts[0][:port]).to be(8080)
525
+ context 'when there is a trailing slash with a path \'http://myhost/foo/bar/\'' do
526
+
527
+ let(:host) do
528
+ 'http://myhost/foo/bar/'
529
+ end
530
+
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
515
536
  end
516
- end
517
537
 
518
- context 'when there is a trailing slash' do
538
+ context 'when the protocol is http' do
519
539
 
520
- let(:host) do
521
- 'http://myhost/'
540
+ context 'when there is no port specified \'http://myhost\'' do
541
+
542
+ let(:host) do
543
+ 'http://myhost'
544
+ end
545
+
546
+ it 'extracts the host' do
547
+ expect(hosts[0][:host]).to eq('myhost')
548
+ end
549
+
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
522
607
  end
523
608
 
524
- it 'extracts the host' do
525
- expect(hosts[0][:host]).to eq('myhost')
526
- expect(hosts[0][:scheme]).to eq('http')
527
- 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
528
701
  end
529
702
  end
530
703
 
531
- context 'when there is a trailing slash with a path' do
704
+ context 'when no protocol is specified \'myhost\'' do
532
705
 
533
706
  let(:host) do
534
- 'http://myhost/foo/bar/'
707
+ 'myhost'
535
708
  end
536
709
 
537
- it 'extracts the host' do
710
+ it 'defaults to http' do
538
711
  expect(hosts[0][:host]).to eq('myhost')
539
- expect(hosts[0][:scheme]).to eq('http')
540
- 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)
541
717
  end
542
718
  end
543
719
  end
544
720
 
545
- context 'when the hosts are a Hash' do
721
+ context 'when the host is a Hash' do
546
722
 
547
723
  let(:host) do
548
724
  { :host => 'myhost', :scheme => 'https' }
@@ -550,7 +726,13 @@ describe Elasticsearch::Transport::Client do
550
726
 
551
727
  it 'extracts the host' do
552
728
  expect(hosts[0][:host]).to eq('myhost')
553
- 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
554
736
  expect(hosts[0][:port]).to be(9200)
555
737
  end
556
738
 
@@ -609,7 +791,13 @@ describe Elasticsearch::Transport::Client do
609
791
 
610
792
  it 'extracts the host' do
611
793
  expect(hosts[0][:host]).to eq('myhost')
794
+ end
795
+
796
+ it 'extracts the protocol' do
612
797
  expect(hosts[0][:scheme]).to eq('https')
798
+ end
799
+
800
+ it 'converts the port to an integer' do
613
801
  expect(hosts[0][:port]).to be(443)
614
802
  end
615
803
  end
@@ -622,7 +810,13 @@ describe Elasticsearch::Transport::Client do
622
810
 
623
811
  it 'extracts the host' do
624
812
  expect(hosts[0][:host]).to eq('myhost')
813
+ end
814
+
815
+ it 'extracts the protocol' do
625
816
  expect(hosts[0][:scheme]).to eq('https')
817
+ end
818
+
819
+ it 'extracts port as an integer' do
626
820
  expect(hosts[0][:port]).to be(443)
627
821
  end
628
822
  end
@@ -636,7 +830,13 @@ describe Elasticsearch::Transport::Client do
636
830
 
637
831
  it 'extracts the host' do
638
832
  expect(hosts[0][:host]).to eq('myhost')
833
+ end
834
+
835
+ it 'extracts the protocol' do
639
836
  expect(hosts[0][:scheme]).to eq('https')
837
+ end
838
+
839
+ it 'converts the port to an integer' do
640
840
  expect(hosts[0][:port]).to be(9200)
641
841
  end
642
842
 
@@ -648,7 +848,13 @@ describe Elasticsearch::Transport::Client do
648
848
 
649
849
  it 'extracts the host' do
650
850
  expect(hosts[0][:host]).to eq('myhost')
851
+ end
852
+
853
+ it 'extracts the protocol' do
651
854
  expect(hosts[0][:scheme]).to eq('https')
855
+ end
856
+
857
+ it 'converts the port to an integer' do
652
858
  expect(hosts[0][:port]).to be(443)
653
859
  end
654
860
  end
@@ -661,7 +867,13 @@ describe Elasticsearch::Transport::Client do
661
867
 
662
868
  it 'extracts the host' do
663
869
  expect(hosts[0][:host]).to eq('myhost')
870
+ end
871
+
872
+ it 'extracts the protocol' do
664
873
  expect(hosts[0][:scheme]).to eq('https')
874
+ end
875
+
876
+ it 'extracts port as an integer' do
665
877
  expect(hosts[0][:port]).to be(443)
666
878
  end
667
879
  end
@@ -677,7 +889,13 @@ describe Elasticsearch::Transport::Client do
677
889
 
678
890
  it 'extracts the host' do
679
891
  expect(hosts[0][:host]).to eq('myhost')
892
+ end
893
+
894
+ it 'extracts the protocol' do
680
895
  expect(hosts[0][:protocol]).to eq('http')
896
+ end
897
+
898
+ it 'defaults to port 9200' do
681
899
  expect(hosts[0][:port]).to be(9200)
682
900
  end
683
901
  end
@@ -690,20 +908,13 @@ describe Elasticsearch::Transport::Client do
690
908
 
691
909
  it 'extracts the host' do
692
910
  expect(hosts[0][:host]).to eq('myhost')
693
- expect(hosts[0][:protocol]).to eq('http')
694
- expect(hosts[0][:port]).to be(9200)
695
911
  end
696
- end
697
912
 
698
- context 'when there is one host with a protocol and no port' do
699
-
700
- let(:host) do
701
- ['http://myhost']
913
+ it 'extracts the protocol' do
914
+ expect(hosts[0][:scheme]).to eq('http')
702
915
  end
703
916
 
704
- it 'extracts the host' do
705
- expect(hosts[0][:host]).to eq('myhost')
706
- expect(hosts[0][:protocol]).to eq('http')
917
+ it 'defaults to port 9200' do
707
918
  expect(hosts[0][:port]).to be(9200)
708
919
  end
709
920
  end
@@ -728,7 +939,7 @@ describe Elasticsearch::Transport::Client do
728
939
  end
729
940
  end
730
941
 
731
- 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
732
943
 
733
944
  let(:host) do
734
945
  ['https://myhost']
@@ -736,12 +947,18 @@ describe Elasticsearch::Transport::Client do
736
947
 
737
948
  it 'extracts the host' do
738
949
  expect(hosts[0][:host]).to eq('myhost')
739
- expect(hosts[0][:protocol]).to eq('https')
740
- 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)
741
958
  end
742
959
  end
743
960
 
744
- 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
745
962
 
746
963
  let(:host) do
747
964
  ['http://myhost/foo/bar']
@@ -749,9 +966,18 @@ describe Elasticsearch::Transport::Client do
749
966
 
750
967
  it 'extracts the host' do
751
968
  expect(hosts[0][:host]).to eq('myhost')
752
- 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
753
976
  expect(hosts[0][:port]).to be(9200)
754
- 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')
755
981
  end
756
982
  end
757
983
 
@@ -761,7 +987,7 @@ describe Elasticsearch::Transport::Client do
761
987
  ['host1', 'host2']
762
988
  end
763
989
 
764
- it 'extracts the host' do
990
+ it 'extracts the hosts' do
765
991
  expect(hosts[0][:host]).to eq('host1')
766
992
  expect(hosts[0][:protocol]).to eq('http')
767
993
  expect(hosts[0][:port]).to be(9200)
@@ -777,7 +1003,7 @@ describe Elasticsearch::Transport::Client do
777
1003
  ['host1:1000', 'host2:2000']
778
1004
  end
779
1005
 
780
- it 'extracts the host' do
1006
+ it 'extracts the hosts' do
781
1007
  expect(hosts[0][:host]).to eq('host1')
782
1008
  expect(hosts[0][:protocol]).to eq('http')
783
1009
  expect(hosts[0][:port]).to be(1000)
@@ -1197,7 +1423,7 @@ describe Elasticsearch::Transport::Client do
1197
1423
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1198
1424
  expect { client.search(opaque_id: 'opaque_id') }.not_to raise_error
1199
1425
  expect(client).to have_received(:perform_request)
1200
- .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1426
+ .with('GET', '_search', { opaque_id: 'opaque_id' }, nil, {})
1201
1427
  end
1202
1428
  end
1203
1429
  end
@@ -1236,7 +1462,28 @@ describe Elasticsearch::Transport::Client do
1236
1462
  allow(client).to receive(:perform_request) { OpenStruct.new(body: '') }
1237
1463
  expect { client.search(headers: headers) }.not_to raise_error
1238
1464
  expect(client).to have_received(:perform_request)
1239
- .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)
1240
1487
  end
1241
1488
  end
1242
1489
  end
@@ -1458,7 +1705,7 @@ describe Elasticsearch::Transport::Client do
1458
1705
  context 'when using the HTTPClient adapter' do
1459
1706
 
1460
1707
  let(:client) do
1461
- 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)
1462
1709
  end
1463
1710
 
1464
1711
  it 'compresses the request and decompresses the response' do