Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error decoding chunked response in _update_chunk_length: ValueError: invalid literal for int() with base 16: b'HTTP/1.1 200 OK\r\n' #4248

Closed
danc86 opened this issue Aug 19, 2017 · 25 comments

Comments

@danc86
Copy link

danc86 commented Aug 19, 2017

Decoding a response with chunked encoding fails because it seems to be reading from the HTTP status line instead of the start of the body.

Expected Result

Successfully return a 200 response object.

Actual Result

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 535, in _update_chunk_length
    self.chunk_left = int(line, 16)
ValueError: invalid literal for int() with base 16: b'HTTP/1.1 200 OK\r\n'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 298, in _error_catcher
    yield
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 590, in read_chunked
    self._update_chunk_length()
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 539, in _update_chunk_length
    raise httplib.IncompleteRead(line)
http.client.IncompleteRead: IncompleteRead(17 bytes read)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/requests/models.py", line 719, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 428, in stream
    for line in self.read_chunked(amt, decode_content=decode_content):
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 618, in read_chunked
    self._original_response.close()
  File "/usr/lib64/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/usr/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 316, in _error_catcher
    raise ProtocolError('Connection broken: %r' % e, e)
requests.packages.urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(17 bytes read)', IncompleteRead(17 bytes read))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python3.6/site-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3.6/site-packages/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3.6/site-packages/requests/sessions.py", line 641, in send
    r.content
  File "/usr/lib/python3.6/site-packages/requests/models.py", line 797, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "/usr/lib/python3.6/site-packages/requests/models.py", line 722, in generate
    raise ChunkedEncodingError(e)
requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(17 bytes read)', IncompleteRead(17 bytes read))

Reproduction Steps

import requests
requests.get('https://my.virginmoney.com.au/AUVMA/JSO/signon/DisplayUsernameSignon.do')

System Information

requests 2.13.0
urllib3 1.20
Python 3.6.2
Fedora 26

@danc86 danc86 changed the title Error decoding chunked response in _update_chunk_length: ValueError: invalid literal for int() with base 16: b'HTTP/1.1 200 OK\r\n' Error decoding chunked response in _update_chunk_length: ValueError: invalid literal for int() with base 16: b'HTTP/1.1 200 OK\r\n' Aug 19, 2017
@danc86
Copy link
Author

danc86 commented Aug 19, 2017

This works fine with requests 2.10.0 so something regressed between then and 2.13.0. Also tested with 2.18.4 and the bug exists as above.

@danc86
Copy link
Author

danc86 commented Aug 19, 2017

I can't spot anything defective or invalid in the response from that server when I look at it manually.

One thing I do notice is that it is using both Content-Encoding: gzip and Transfer-Encoding: chunked which might be a little unusual. Could this bug be caused by some bad interaction between the gzip decoding and chunk decoding?

@Lukasa
Copy link
Member

Lukasa commented Aug 19, 2017

I can't reproduce this with Requests 2.18.4 on either Python 3 or Python 2. Have you tried updating urllib3 to check if this resolves the problem?

@danc86
Copy link
Author

danc86 commented Aug 20, 2017

Okay sorry, my comment above about 2.10.0 vs. 2.13.0 was incorrect. I did not thoroughly test all the combinations. It turns out this works fine with all versions/combinations of requests and urllib3 that I tested on Fedora 25 but fails with all versions/combinations of requests and urllib3 that I tested on Fedora 26.

Which most likely means: it's something specific to Python 3.6?

@Lukasa
Copy link
Member

Lukasa commented Aug 20, 2017

Or at least Fedora 36, as it works fine for me with my Python 3.6.2 on macOS. I recommend reporting a bug with Fedora.

@siddhi
Copy link

siddhi commented Apr 14, 2018

I get this error on Windows with the latest Python 3.7 alpha and latest requests / urllib3. When I use Python 3.5 then it works fine with the same requests / urllib3. I'm suspecting a python version issue as well.

@danc86
Copy link
Author

danc86 commented Apr 26, 2018

I haven't dug into this in a while. Back when I was looking at it, I could not find any substantial differences between Fedora 25 and 26 in Python land at all (same Python version, same version of all the relevant Python libraries I could see, same code for urllib3 and requests) but one big difference did stand out: Fedora 25 has openssl 1.0.2 whereas Fedora 26+ has openssl 1.1.0. Not sure if that is related.

@cedric05
Copy link

cedric05 commented Jun 18, 2018

i'm facing same kind of issue. any idea how to bypass this?

<Response [200]>
Traceback (most recent call last):
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 539, in _update_chunk_length
    self.chunk_left = int(line, 16)
ValueError: invalid literal for int() with base 16: b''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 302, in _error_catcher
    yield
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 594, in read_chunked
    self._update_chunk_length()
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 543, in _update_chunk_length
    raise httplib.IncompleteRead(line)
http.client.IncompleteRead: IncompleteRead(0 bytes read)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/models.py", line 738, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 432, in stream
    for line in self.read_chunked(amt, decode_content=decode_content):
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 622, in read_chunked
    self._original_response.close()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py", line 100, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/packages/urllib3/response.py", line 320, in _error_catcher
    raise ProtocolError('Connection broken: %r' % e, e)
requests.packages.urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "loginscheck.py", line 49, in <module>
    f.write(req.text)
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/models.py", line 840, in text
    if not self.content:
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/models.py", line 816, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "/Users/officeuse/environs/py_elt_service/lib/python3.6/site-packages/requests/models.py", line 741, in generate
    raise ChunkedEncodingError(e)
requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))

@odboy
Copy link

odboy commented Jul 29, 2018

I solved this problem by adding one line code.

python3 on Mac
urllib3 == 1.23
requests == 2.19.1

Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/response.py", line 574, in _update_chunk_length
self.chunk_left = int(line, 16)
ValueError: invalid literal for int() with base 16: b''

so, I open the file "......./urllib3/response.py", add line = (len(line)>0 and line or "0") in 571, like below:

    def _update_chunk_length(self):
        # First, we'll figure out length of a chunk and then
        # we'll try to read it from socket.
        if self.chunk_left is not None:
            return
        line = self._fp.fp.readline()
        line = line.split(b';', 1)[0]
        line = (len(line)>0 and line or "0")     # added this line
        try:
            self.chunk_left = int(line, 16)
        except ValueError:
            # Invalid chunked protocol response, abort.
            self.close()
            raise httplib.IncompleteRead(line)

@cosminnastasie
Copy link

I solved this problem by adding one line code.

python3 on Mac
urllib3 == 1.23
requests == 2.19.1

Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/response.py", line 574, in _update_chunk_length
self.chunk_left = int(line, 16)
ValueError: invalid literal for int() with base 16: b''

so, I open the file "......./urllib3/response.py", add line = (len(line)>0 and line or "0") in 571, like below:

    def _update_chunk_length(self):
        # First, we'll figure out length of a chunk and then
        # we'll try to read it from socket.
        if self.chunk_left is not None:
            return
        line = self._fp.fp.readline()
        line = line.split(b';', 1)[0]
        line = (len(line)>0 and line or "0")     # added this line
        try:
            self.chunk_left = int(line, 16)
        except ValueError:
            # Invalid chunked protocol response, abort.
            self.close()
            raise httplib.IncompleteRead(line)

It looks that ths line fixes the problem for me. Can you please explain what this line do?

@KonMann
Copy link

KonMann commented Oct 4, 2018

Shouldn't this then be fixed in urllib3? @Lukasa

@sigmavirus24
Copy link
Contributor

@KonMann yes it should.

@odboy
Copy link

odboy commented Oct 9, 2018

@cosminnastasie I am a little forgotten. It seems like that without this line, there should be occur problem at the last chunk data. when the value of 'line' is Null, the error arise.

@odboy
Copy link

odboy commented Oct 9, 2018

@cosminnastasie

>>> line = b''
>>> line = line.split(b';', 1)[0]
>>> int(line,16)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 16: b''

but if we add that line:

>>> line = b''
>>> line = line.split(b';', 1)[0]
>>> line = (len(line)>0 and line or "0")     # added this line
>>> int(line,16)
0

problem solved!!!

@KonMann
Copy link

KonMann commented Oct 9, 2018

@sigmavirus24 ok, as far as I can see there is no open issue about this in the Urllib3 Issue Tracker at the moment => Let's open an issue there?

@sigmavirus24
Copy link
Contributor

@KonMann you seem to have more time than me. Go for it.

@KonMann
Copy link

KonMann commented Oct 10, 2018

@odboy Do you have some code to reproduce?

@hixss
Copy link

hixss commented Oct 12, 2018

We temporarily repaired it in this way. I wonder if there will be any problem.

def _update_chunk_length(self):
    # First, we'll figure out length of a chunk and then
    # we'll try to read it from socket.
    if self.chunk_left is not None:
        return
    line = self._fp.fp.readline()
    line = line.split(b';', 1)[0]
    try:
        if len(line) == 0:
            self.chunk_left = 0
        else:
            self.chunk_left = int(line, 16)
    except ValueError:
        # Invalid chunked protocol response, abort.
        self.close()
        raise httplib.IncompleteRead(line)

@fildred13
Copy link

I'm running into this exact issue as well, with an identical traceback as #4248 (comment). I've tried reverting requests as far back as 2.9.1, and as far forward as the current release (2.20.1), with a few different combinations of urllib3 versions in each case - they all give the exact same traceback.

Is there a release which we can use until this is fixed, or do we have to patch our requests with the above corrected def?

@dulitz
Copy link

dulitz commented Feb 2, 2019

I am having this issue as well, and I agree the problem is at the urllib3 level.

@pheanex
Copy link

pheanex commented Feb 4, 2019

Can we agree on where we want this issue to be fixed? Here in requests or in urllib3?

@sigmavirus24
Copy link
Contributor

The underlying exception comes from urllib3, but as @dulitz explained in urllib3/urllib3#1516, this isn't necessarily always a "bug" in requests or urllib3. So "fixing" it might not be easy or possible. Regardless, I'm closing this issue here.

@mbatle
Copy link

mbatle commented Jul 6, 2019

I am able to reproduce the same bug by using this code

import requests
requests.get('https://www.telecreditobcp.com/tlcnp/index.do')

I think this is a bug in the server side, but maybe urllib3 could do a better job workarounding this bug in the server, as other libraries / applications do for example (same URL works ok in a web browser like chrome or firefox ...)

@mbatle
Copy link

mbatle commented Jul 10, 2019

As far as I could see, the server (in the example above) sends chunked transfer, but it does not send properly the last 0-length chunk and returns the response code. That's where urllib3 raises exception when trying to decode the length of the chunk from the response status code line. Some insights I could find so far:

  • the same request works in a browser without complain (I have tried sending same headers than the browser but didn't see a different for the sample code reproducing the bug)

  • sometimes the request works perfectly with the sample code for a while, and then stops working again. So as our local side has not changed really, I assume there is some load balancing or something and we are served by another server maybe with possibly a slightly different version of software.

  • the following code makes it deliver part of the content but still not the full content:

r = requests.get('https://www.telecreditobcp.com/tlcnp/index.do', stream=True)
for line in r.iter_lines():
print(line)

  • the bug in my local environment happens with python 3.6.8, 3.7.3 and 2.7.16 versions in Linux. Have tried same kernel though (5.1.16-300.fc30.x86_64).

  • Have tried with Ubuntu and Fedora, both seem to fail same way.

  • I have a server in AWS running Linux with python 3.5.2, and it works always, no bugs

  • I've been told the bug seems not reproducible in Windows environment with any version.

  • I've been told enabling traffic through a VPN makes it work in a Linux environment that used to fail.

  • same bug seems to happen with curl
    curl -X GET https://www.telecreditobcp.com/tlcnp/index.do

curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding

fdriesenaar pushed a commit to dappre/QiyTestTool that referenced this issue Aug 8, 2019
- Changed: /qiy_nodes/{}/events
New: silenced Empty exception

See also: psf/requests#4248

2019-08-08 08:08:41,858: Exception in thread mgd_dev2.events_listener:
2019-08-08 08:08:41,859: Traceback (most recent call last):
2019-08-08 08:08:41,859:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 639, in _update_chunk_length
2019-08-08 08:08:41,859:     self.chunk_left = int(line, 16)
2019-08-08 08:08:41,859: ValueError: invalid literal for int() with base 16: b''
2019-08-08 08:08:41,859:
2019-08-08 08:08:41,860: During handling of the above exception, another exception occurred:
2019-08-08 08:08:41,860:
2019-08-08 08:08:41,860: Traceback (most recent call last):
2019-08-08 08:08:41,860:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 397, in _error_catcher
2019-08-08 08:08:41,860:     yield
2019-08-08 08:08:41,860:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 704, in read_chunked
2019-08-08 08:08:41,861:     self._update_chunk_length()
2019-08-08 08:08:41,861:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 643, in _update_chunk_length
2019-08-08 08:08:41,861:     raise httplib.IncompleteRead(line)
2019-08-08 08:08:41,861: http.client.IncompleteRead: IncompleteRead(0 bytes read)
2019-08-08 08:08:41,861:
2019-08-08 08:08:41,861: During handling of the above exception, another exception occurred:
2019-08-08 08:08:41,862:
2019-08-08 08:08:41,862: Traceback (most recent call last):
2019-08-08 08:08:41,862:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/requests/models.py", line 750, in generate
2019-08-08 08:08:41,862:     for chunk in self.raw.stream(chunk_size, decode_content=True):
2019-08-08 08:08:41,862:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 527, in stream
2019-08-08 08:08:41,862:     for line in self.read_chunked(amt, decode_content=decode_content):
2019-08-08 08:08:41,863:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 732, in read_chunked
2019-08-08 08:08:41,863:     self._original_response.close()
2019-08-08 08:08:41,863:   File "/usr/lib/python3.6/contextlib.py", line 100, in __exit__
2019-08-08 08:08:41,863:     self.gen.throw(type, value, traceback)
2019-08-08 08:08:41,863:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/urllib3/response.py", line 415, in _error_catcher
2019-08-08 08:08:41,864:     raise ProtocolError('Connection broken: %r' % e, e)
2019-08-08 08:08:41,864: urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))
2019-08-08 08:08:41,864:
2019-08-08 08:08:41,864: During handling of the above exception, another exception occurred:
2019-08-08 08:08:41,864:
2019-08-08 08:08:41,864: Traceback (most recent call last):
2019-08-08 08:08:41,865:   File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
2019-08-08 08:08:41,865:     self.run()
2019-08-08 08:08:41,865:   File "/usr/lib/python3.6/threading.py", line 864, in run
2019-08-08 08:08:41,865:     self._target(*self._args, **self._kwargs)
2019-08-08 08:08:41,865:   File "/home/fdriesenaar/QiyTestTool/QiyTestTool/site/flask_app.py", line 196, in node_events_listener
2019-08-08 08:08:41,865:     for chunk in r.iter_content(chunk_size=1, decode_unicode=True):
2019-08-08 08:08:41,866:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/requests/utils.py", line 505, in stream_decode_response_unicode
2019-08-08 08:08:41,866:     for chunk in iterator:
2019-08-08 08:08:41,866:   File "/home/fdriesenaar/.local/lib/python3.6/site-packages/requests/models.py", line 753, in generate
2019-08-08 08:08:41,866:     raise ChunkedEncodingError(e)
2019-08-08 08:08:41,866: requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))
2019-08-08 08:08:41,866:
2019-08-08 08:09:51,825: Error running WSGI application
2019-08-08 08:09:51,828: queue.Empty
2019-08-08 08:09:51,828:   File "/usr/local/lib/python3.6/dist-packages/werkzeug/wsgi.py", line 703, in __next__
2019-08-08 08:09:51,828:     return self._next()
2019-08-08 08:09:51,829:
2019-08-08 08:09:51,829:   File "/usr/local/lib/python3.6/dist-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
2019-08-08 08:09:51,829:     for item in iterable:
2019-08-08 08:09:51,829:
2019-08-08 08:09:51,829:   File "/home/fdriesenaar/QiyTestTool/QiyTestTool/site/flask_app.py", line 913, in gen
2019-08-08 08:09:51,830:     event=queue.get(timeout=100)
2019-08-08 08:09:51,830:
2019-08-08 08:09:51,830:   File "/usr/lib/python3.6/queue.py", line 172, in get
2019-08-08 08:09:51,830:     raise Empty
@aswath-kumar
Copy link

line = (len(line)>0 and line or "0") # added this line

Solved my problem. Man is a LEGEND.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests