elasticsearch-transport 7.10.0.pre → 7.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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