diff --git a/elasticsearch/Gemfile b/elasticsearch/Gemfile index 21c38fe23..9fd65ae5b 100644 --- a/elasticsearch/Gemfile +++ b/elasticsearch/Gemfile @@ -31,3 +31,6 @@ if ENV['TRANSPORT_VERSION'] == 'main' end gem 'opentelemetry-sdk', require: false if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0') +if defined?(JRUBY_VERSION) + gem 'manticore', platform: :jruby +end diff --git a/elasticsearch/lib/elasticsearch.rb b/elasticsearch/lib/elasticsearch.rb index 3bf2e7930..e27c79cd4 100644 --- a/elasticsearch/lib/elasticsearch.rb +++ b/elasticsearch/lib/elasticsearch.rb @@ -189,10 +189,10 @@ def set_user_agent!(arguments) def set_content_type!(arguments) headers = {} user_headers = arguments&.[](:transport_options)&.[](:headers) - unless user_headers&.keys&.detect { |h| h =~ /content-?_?type/ } + unless user_headers&.keys&.detect { |h| h =~ /content-?_?type/i } headers['content-type'] = 'application/vnd.elasticsearch+json; compatible-with=9' end - unless user_headers&.keys&.detect { |h| h =~ /accept/ } + unless user_headers&.keys&.detect { |h| h =~ /accept/i } headers['accept'] = 'application/vnd.elasticsearch+json; compatible-with=9' end set_header(headers, arguments) unless headers.empty? diff --git a/elasticsearch/spec/unit/headers_spec.rb b/elasticsearch/spec/unit/headers_spec.rb index 3751c7448..f8d516fc2 100644 --- a/elasticsearch/spec/unit/headers_spec.rb +++ b/elasticsearch/spec/unit/headers_spec.rb @@ -73,20 +73,18 @@ expect_any_instance_of(Faraday::Connection) .to receive(:run_request) - .with(:get, 'http://localhost:9200/_search', nil, connection_headers) { OpenStruct.new(body: '') } + .with(:get, 'http://localhost:9200/_search', nil, connection_headers) { OpenStruct.new(body: '') } client.search end end context 'when content-type header is changed' do let!(:client) do - described_class.new( - host: 'http://localhost:9200', - transport_options: { headers: instance_headers } - ).tap do |client| + described_class.new(transport_options: { headers: instance_headers }).tap do |client| client.instance_variable_set('@verified', true) end end + let(:instance_headers) do { content_type: 'application/json' } end @@ -98,11 +96,88 @@ expect_any_instance_of(Faraday::Connection) .to receive(:run_request) - .with(:get, 'http://localhost:9200/_search', nil, connection_headers) { OpenStruct.new(body: '') } + .with(:get, 'http://localhost:9200/_search', nil, connection_headers) { OpenStruct.new(body: '') } + client.search + end + end + + context 'when Content-Type header is used' do + let(:client) do + described_class.new(transport_options: { headers: instance_headers }).tap do |client| + client.instance_variable_set('@verified', true) + end + end + + let(:instance_headers) do + { 'Content-Type' => 'application/text' } + end + + it 'performs the request with the header' do + connection_headers = client.transport.connections.connections.first.connection.headers + expect(connection_headers['Accept']).to eq 'application/vnd.elasticsearch+json; compatible-with=9' + expect(connection_headers['Content-Type']).to eq 'application/text' + + expect_any_instance_of(Faraday::Connection) + .to receive(:run_request) + .with(:get, 'http://localhost:9200/_search', nil, connection_headers) { OpenStruct.new(body: '') } client.search end end + if defined?(JRUBY_VERSION) + context 'Using Manticore with JRuby' do + let(:client) do + require 'elastic/transport/transport/http/manticore' + described_class.new( + transport_class: Elastic::Transport::Transport::HTTP::Manticore, + transport_options: { headers: instance_headers } + ).tap do |client| + client.instance_variable_set('@verified', true) + end + end + + context 'when Content-Type header is used' do + let(:instance_headers) do + { 'Content-Type' => 'application/text' } + end + + it 'does not duplicate content-type the header' do + connection_headers = client.transport.connections.connections.first.connection.instance_variable_get('@options')[:headers] + expect(connection_headers['accept']).to eq 'application/vnd.elasticsearch+json; compatible-with=9' + expect(connection_headers['content-type']).to be nil + expect(connection_headers.fetch('Content-Type')).to eq 'application/text' + + expect_any_instance_of(Manticore::Client) + .to receive(:get).with( + 'http://localhost:9200/_search', + { headers: connection_headers } + ) { OpenStruct.new(body: '') } + client.search + end + + context 'when content-type header is used' do + let(:instance_headers) do + { 'content-type' => 'application/text' } + end + + it 'does not duplicate Content-Type the header' do + connection_headers = client.transport.connections.connections.first.connection.instance_variable_get('@options')[:headers] + expect(connection_headers['accept']).to eq 'application/vnd.elasticsearch+json; compatible-with=9' + expect(connection_headers['content-type']).to be nil + expect(connection_headers.fetch('Content-Type')).to eq 'application/text' + + expect_any_instance_of(Manticore::Client) + .to receive(:get).with( + 'http://localhost:9200/_search', + { headers: connection_headers } + ) { OpenStruct.new(body: '') } + client.search + end + end + end + end + end + context 'when no header is set, uses v9 content-type and accept' do let!(:client) do described_class.new(host: 'http://localhost:9200').tap do |client| @@ -117,7 +192,7 @@ expect_any_instance_of(Faraday::Connection) .to receive(:run_request) - .with(:get, 'http://localhost:9200/_search', nil, expected_headers) { OpenStruct.new(body: '') } + .with(:get, 'http://localhost:9200/_search', nil, expected_headers) { OpenStruct.new(body: '') } client.search end end