Skip to content

Commit e40c48b

Browse files
committed
[CLIENT] Support compression when using Curb adapter
1 parent 83dd53d commit e40c48b

File tree

5 files changed

+115
-28
lines changed

5 files changed

+115
-28
lines changed

elasticsearch-transport/lib/elasticsearch/transport/transport/base.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,27 @@ def host_unreachable_exceptions
371371
CONTENT_TYPE_REGEX = /content\-?\_?type/
372372
DEFAULT_CONTENT_TYPE = 'application/json'.freeze
373373
GZIP = 'gzip'.freeze
374+
ACCEPT_ENCODING = 'Accept-Encoding'.freeze
375+
GZIP_FIRST_TWO_BYTES = '1f8b'.freeze
376+
HEX_STRING_DIRECTIVE = 'H*'.freeze
377+
RUBY_ENCODING = '1.9'.respond_to?(:force_encoding)
378+
379+
def decompress_response(body)
380+
return body unless use_compression?
381+
return body unless gzipped?(body)
382+
383+
io = StringIO.new(body)
384+
gzip_reader = if RUBY_ENCODING
385+
Zlib::GzipReader.new(io, :encoding => 'ASCII-8BIT')
386+
else
387+
Zlib::GzipReader.new(io)
388+
end
389+
gzip_reader.read
390+
end
391+
392+
def gzipped?(body)
393+
body[0..1].unpack(HEX_STRING_DIRECTIVE)[0] == GZIP_FIRST_TWO_BYTES
394+
end
374395

375396
def use_compression?
376397
@compression

elasticsearch-transport/lib/elasticsearch/transport/transport/http/curb.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,15 @@ def perform_request(method, path, params={}, body=nil, headers=nil)
4343
connection.connection.set :nobody, false
4444

4545
connection.connection.put_data = __convert_to_json(body) if body
46-
connection.connection.headers = headers if headers
46+
47+
if headers
48+
if connection.connection.headers
49+
connection.connection.headers.merge(headers)
50+
else
51+
connection.connection.headers = headers
52+
end
53+
end
54+
4755
else raise ArgumentError, "Unsupported HTTP method: #{method}"
4856
end
4957

@@ -53,7 +61,7 @@ def perform_request(method, path, params={}, body=nil, headers=nil)
5361
response_headers['content-type'] = 'application/json' if connection.connection.header_str =~ /\/json/
5462

5563
Response.new connection.connection.response_code,
56-
connection.connection.body_str,
64+
decompress_response(connection.connection.body_str),
5765
response_headers
5866
end
5967
end
@@ -96,6 +104,18 @@ def host_unreachable_exceptions
96104

97105
private
98106

107+
def apply_headers(client, options)
108+
super
109+
110+
if use_compression?
111+
if client.headers
112+
client.headers[ACCEPT_ENCODING] = GZIP
113+
else
114+
client.headers = { ACCEPT_ENCODING => GZIP }
115+
end
116+
end
117+
end
118+
99119
def user_agent_header(client)
100120
@user_agent ||= begin
101121
meta = ["RUBY_VERSION: #{RUBY_VERSION}"]

elasticsearch-transport/lib/elasticsearch/transport/transport/http/faraday.rb

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def perform_request(method, path, params={}, body=nil, headers=nil)
4242
( body ? __convert_to_json(body) : nil ),
4343
headers)
4444

45-
Response.new response.status, decompress_response(response), response.headers
45+
Response.new response.status, decompress_response(response.body), response.headers
4646
end
4747
end
4848

@@ -67,28 +67,6 @@ def host_unreachable_exceptions
6767

6868
private
6969

70-
GZIP_FIRST_TWO_BYTES = '1f8b'.freeze
71-
HEX_STRING_DIRECTIVE = 'H*'.freeze
72-
RUBY_ENCODING = '1.9'.respond_to?(:force_encoding)
73-
74-
def decompress_response(response)
75-
body = response.body
76-
return body unless use_compression?
77-
return body unless gzipped?(body)
78-
79-
io = StringIO.new(body)
80-
gzip_reader = if RUBY_ENCODING
81-
Zlib::GzipReader.new(io, :encoding => 'ASCII-8BIT')
82-
else
83-
Zlib::GzipReader.new(io)
84-
end
85-
gzip_reader.read
86-
end
87-
88-
def gzipped?(body)
89-
body[0..1].unpack(HEX_STRING_DIRECTIVE)[0] == GZIP_FIRST_TWO_BYTES
90-
end
91-
9270
def user_agent_header(client)
9371
@user_agent ||= begin
9472
meta = ["RUBY_VERSION: #{RUBY_VERSION}"]

elasticsearch-transport/spec/elasticsearch/transport/client_spec.rb

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
end
106106
end
107107

108-
context 'when the Curb transport class is used' do
108+
context 'when the Curb transport class is used', unless: jruby? do
109109

110110
let(:client) do
111111
described_class.new(transport_class: Elasticsearch::Transport::Transport::HTTP::Curb)
@@ -1252,6 +1252,14 @@
12521252
it 'sets the options on the transport' do
12531253
expect(client.perform_request('GET', '/').body).to be_a(Hash)
12541254
end
1255+
1256+
it 'sets the Accept-Encoding header' do
1257+
expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1258+
end
1259+
1260+
it 'preserves the other headers' do
1261+
expect(client.transport.connections[0].connection.headers['User-Agent'])
1262+
end
12551263
end
12561264

12571265
context 'when using the HTTPClient adapter' do
@@ -1263,9 +1271,17 @@
12631271
it 'sets the options on the transport' do
12641272
expect(client.perform_request('GET', '/').body).to be_a(Hash)
12651273
end
1274+
1275+
it 'sets the Accept-Encoding header' do
1276+
expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1277+
end
1278+
1279+
it 'preserves the other headers' do
1280+
expect(client.transport.connections[0].connection.headers['User-Agent'])
1281+
end
12661282
end
12671283

1268-
context 'when using the Patron adapter' do
1284+
context 'when using the Patron adapter', unless: jruby? do
12691285

12701286
let(:client) do
12711287
described_class.new(hosts: ELASTICSEARCH_HOSTS, compression: true, adapter: :patron)
@@ -1274,6 +1290,14 @@
12741290
it 'sets the options on the transport' do
12751291
expect(client.perform_request('GET', '/').body).to be_a(Hash)
12761292
end
1293+
1294+
it 'sets the Accept-Encoding header' do
1295+
expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1296+
end
1297+
1298+
it 'preserves the other headers' do
1299+
expect(client.transport.connections[0].connection.headers['User-Agent'])
1300+
end
12771301
end
12781302

12791303
context 'when using the Net::HTTP::Persistent adapter' do
@@ -1296,9 +1320,51 @@
12961320
it 'sets the options on the transport' do
12971321
expect(client.perform_request('GET', '/').body).to be_a(Hash)
12981322
end
1323+
1324+
it 'sets the Accept-Encoding header' do
1325+
expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1326+
end
1327+
1328+
it 'preserves the other headers' do
1329+
expect(client.transport.connections[0].connection.headers['User-Agent'])
1330+
end
12991331
end
13001332
end
13011333
end
1334+
1335+
context 'when using Curb as the transport', unless: jruby? do
1336+
1337+
let(:client) do
1338+
described_class.new(hosts: ELASTICSEARCH_HOSTS,
1339+
compression: true,
1340+
transport_class: Elasticsearch::Transport::Transport::HTTP::Curb)
1341+
end
1342+
1343+
it 'sets the Accept-Encoding header' do
1344+
expect(client.transport.connections[0].connection.headers['Accept-Encoding'])
1345+
end
1346+
1347+
it 'preserves the other headers' do
1348+
expect(client.transport.connections[0].connection.headers['User-Agent'])
1349+
end
1350+
1351+
it 'sets the options on the transport' do
1352+
expect(client.perform_request('GET', '/').body).to be_a(Hash)
1353+
end
1354+
end
1355+
1356+
context 'when using Manticore as the transport', if: jruby? do
1357+
1358+
let(:client) do
1359+
described_class.new(hosts: ELASTICSEARCH_HOSTS,
1360+
compression: true,
1361+
transport_class: Elasticsearch::Transport::Transport::HTTP::Manticore)
1362+
end
1363+
1364+
it 'sets the options on the transport' do
1365+
expect(client.perform_request('GET', '/').body).to be_a(Hash)
1366+
end
1367+
end
13021368
end
13031369

13041370
describe '#perform_request' do

elasticsearch-transport/spec/spec_helper.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
require 'ansi/code'
55
require 'hashie/mash'
66
require 'pry-nav'
7-
unless defined?(JRUBY_VERSION)
7+
if defined?(JRUBY_VERSION)
8+
require 'elasticsearch/transport/transport/http/manticore'
9+
else
810
require 'elasticsearch/transport/transport/http/curb'
911
require 'curb'
1012
end

0 commit comments

Comments
 (0)