Elasticsearch-py: http_compress=True results in ProtocolError(('Connection aborted.', BadStatusLine("''",)))

Created on 16 Oct 2018  路  8Comments  路  Source: elastic/elasticsearch-py

es = Elasticsearch(hosts=['http://localhost:9200'], http_compress=True)
res = es.index(index="test-index", doc_type='testtype', body={'text': 'test'})

raises

  File "tst.py", line 16, in main
    res = es.index(index="test-index", doc_type='testtype', body=doc)
  File "/home/ubuntu/venv/local/lib/python2.7/site-packages/elasticsearch/client/utils.py", line 76, in _wrapped
    return func(*args, params=params, **kwargs)
  File "/home/ubuntu/venv/local/lib/python2.7/site-packages/elasticsearch/client/__init__.py", line 319, in index
    _make_path(index, doc_type, id), params=params, body=body)
  File "/home/ubuntu/venv/local/lib/python2.7/site-packages/elasticsearch/transport.py", line 318, in perform_request
    status, headers_response, data = connection.perform_request(method, url, params, body, headers=headers, ignore=ignore, timeout=timeout)
  File "/home/ubuntu/venv/local/lib/python2.7/site-packages/elasticsearch/connection/http_urllib3.py", line 181, in perform_request
    raise ConnectionError('N/A', str(e), e)
elasticsearch.exceptions.ConnectionError: ConnectionError(('Connection aborted.', BadStatusLine("''",))) caused by: ProtocolError(('Connection aborted.', BadStatusLine("''",)))

If I disable http_compress, it works as expected.

Env:

elasticsearch-6.3.1
urllib3-1.23
elasticsearch-oss  6.4.2
http.compression: true
Ubuntu 18.04.1

All 8 comments

Looks like a correlated message in the server log:

2018-10-16T09:49:55,787][WARN ][o.e.h.n.Netty4HttpServerTransport] [test] caught exception while handling client http traffic, closing connection [id: 0x8d51d922, L:/127.0.0.1:9200 ! R:/127.0.0.1:36162]
io.netty.handler.codec.compression.DecompressionException: Input is not in the GZIP format
        at io.netty.handler.codec.compression.JdkZlibDecoder.readGZIPHeader(JdkZlibDecoder.java:244) ~[netty-codec-4.1.16.Final.jar:4.1.16.Final]
        at io.netty.handler.codec.compression.JdkZlibDecoder.decode(JdkZlibDecoder.java:153) ~[netty-codec-4.1.16.Final.jar:4.1.16.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[netty-codec-4.1.16.Final.jar:4.1.16.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[netty-codec-4.1.16.Final.jar:4.1.16.Final]

Hi @fillest ,

I tried to reproduce the issue with the same configuration you mentioned and I was not able to do so. Seems to be working as expected.

Can you run a tcpdump and check the headers for the requests?
tcpdump -vvvs 1024 -l -A -i <loopback_interface> port 9200 for Eg: tcpdump -vvvs 1024 -l -A -i lo0 port 9200

Watch the output of this and run the script you have, this should dump the headers being used for the request. This should tell us what's happening in your case.

Hi guys, I'm having the same issue.
Python 2.7, elasticsearch==6.3.0 + elasticsearch-dsl==6.3.0
working with Elasticsearch 6.3.0 and trying to use the compression:
Elasticsearch(hosts=hosts_for_connection, http_compress=True)

while debugging it I see in http_urllib3.py that body is compressed with zlib (last line):

            if self.http_compress and body:
                try:
                    body = gzip.compress(body)
                except AttributeError:
                    # oops, Python2.7 doesn't have `gzip.compress` let's try
                    # again
                    body = gzip.zlib.compress(body)

With tcpdump I see the headers:

Host: localhsot:9200
Content-Length: 206
connection: keep-alive
content-type: application/json
accept-encoding: gzip,deflate
content-encoding: gzip

The query is built by elasticsearch-dsl. Any idea what's wrong?

I am also facing the same issue as described by @itayB. With http_compress = True it's not working and without that param, it's working.

It works with python 3.7 and reproduced in python 2.7

I think that a workaround might be to choose a different transport layer (but I didn't check if it really compressing requests) :
Elasticsearch(hosts=[{"host": "localhost", "port": 9200}], connection_class=RequestsHttpConnection, http_compress=True)

Note that it requires requests installation: pip install requests

After compare result between failed in python 2.7 and works in python3.6, the error product in module /elasticsearch6/connection/http_urllib3.py, which using zip format instead of gzip format;
should using following code in Python 2.7 to generate gzip format:

deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS)
gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)

text = '''test'''
deflate_data = deflate_compress.compress(text) + deflate_compress.flush()
zlib_data = zlib_compress.compress(text) + zlib_compress.flush()
gzip_data = gzip_compress.compress(text) + gzip_compress.flush()

See as:
https://stackoverflow.com/questions/3122145/zlib-error-error-3-while-decompressing-incorrect-header-check

BTW: work around is OK to me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

juancar1979 picture juancar1979  路  4Comments

jrobison-sb picture jrobison-sb  路  5Comments

edemauro picture edemauro  路  4Comments

thekofimensah picture thekofimensah  路  3Comments

grepsr picture grepsr  路  3Comments