This issue tracker has been migrated to GitHub , and is currently read-only .
For more information, see the GitHub FAQs in the Python's Developer Guide.

Created on 2020-07-20 11:43 by Michal Arbet , last changed 2022-04-11 14:59 by admin . This issue is now closed .

Files File name Uploaded Description mycap.pcap Michal Arbet , 2020-07-20 11:43 I'm not sure if this is really python bug, but I hope that you can check the issue. Issue is that from time to time i'm getting exception from python when sending request to server which has http keepalive option turned on. Requests send a request but in few miliseconds apache2 server is closing persistent connection by sending FIN packet which generate traceback. I can reproduce it by following simple script. #!/usr/bin/python3 import requests from time import sleep import logging logging.basicConfig(level=logging.DEBUG) s = requests.Session() s.verify = False # self-signed cert counter = 0 txt = "test" while True: counter = counter + 1 s.post(' http://localhost ', data={counter:txt}) sleep(5) Everything is working fine, but from time to time I get following traceback. When FIN is received right after request was sent. michalarbet@pixla :~/work$ ./request_test.py DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:80 DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost DEBUG:urllib3.connectionpool: http://localhost:80 "POST / HTTP/1.1" 200 0 Traceback (most recent call last): File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 665, in urlopen httplib_response = self._make_request( File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 421, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 416, in _make_request httplib_response = conn.getresponse() File "/usr/lib/python3.8/ http/client.py ", line 1332, in getresponse response.begin() File "/usr/lib/python3.8/ http/client.py ", line 303, in begin version, status, reason = self._read_status() File "/usr/lib/python3.8/ http/client.py ", line 272, in _read_status raise RemoteDisconnected("Remote end closed connection without" http.client.RemoteDisconnected: Remote end closed connection without response During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/michalarbet/.local/lib/python3.8/site-packages/requests/adapters.py", line 439, in send resp = conn.urlopen( File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 719, in urlopen retries = retries.increment( File "/usr/lib/python3/ dist-packages/urllib3/util/retry.py ", line 400, in increment raise six.reraise(type(error), error, _stacktrace) File "/usr/lib/python3/ dist-packages/six.py ", line 702, in reraise raise value.with_traceback(tb) File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 665, in urlopen httplib_response = self._make_request( File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 421, in _make_request six.raise_from(e, None) File "<string>", line 3, in raise_from File "/usr/lib/python3/ dist-packages/urllib3/connectionpool.py ", line 416, in _make_request httplib_response = conn.getresponse() File "/usr/lib/python3.8/ http/client.py ", line 1332, in getresponse response.begin() File "/usr/lib/python3.8/ http/client.py ", line 303, in begin version, status, reason = self._read_status() File "/usr/lib/python3.8/ http/client.py ", line 272, in _read_status raise RemoteDisconnected("Remote end closed connection without" urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "./request_test.py", line 26, in <module> s.post(' http://localhost ', data={counter:txt}) File "/home/michalarbet/.local/lib/python3.8/site-packages/requests/sessions.py", line 578, in post return self.request('POST', url, data=data, json=json, **kwargs) File "/home/michalarbet/.local/lib/python3.8/site-packages/requests/sessions.py", line 530, in request resp = self.send(prep, **send_kwargs) File "/home/michalarbet/.local/lib/python3.8/site-packages/requests/sessions.py", line 643, in send r = adapter.send(request, **kwargs) File "/home/michalarbet/.local/lib/python3.8/site-packages/requests/adapters.py", line 498, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) Apache using keepalive. /etc/apache2/apache2.conf:KeepAliveTimeout 5 /etc/apache2/apache2.conf:MaxKeepAliveRequests 100 /etc/apache2/apache2.conf:KeepAlive On Sending also pcap file from different reproduce test, but behaviour is same.
I'm using  Ubuntu 20.04 with dist apache2 and default settings :
michalarbet@pixla:~/work$ dpkg -l | grep apache
ii  apache2                                    2.4.41-4ubuntu3
          amd64        Apache HTTP Server
ii  apache2-bin                                2.4.41-4ubuntu3
          amd64        Apache HTTP Server (modules and other binary files)
ii  apache2-data                               2.4.41-4ubuntu3
          all          Apache HTTP Server (common files)
ii  apache2-utils                              2.4.41-4ubuntu3
          amd64        Apache HTTP Server (utility programs for web servers)
ii  libapache2-mod-php                         2:7.4+75
         all          server-side, HTML-embedded scripting language (Apache
2 module) (default)
ii  libapache2-mod-php7.4                      7.4.3-4ubuntu2.2
         amd64        server-side, HTML-embedded scripting language (Apache
2 module)
michalarbet@pixla:~/work$ uname -a
Linux pixla 5.4.0-40-generic #44-Ubuntu SMP Tue Jun 23 00:01:04 UTC 2020
x86_64 x86_64 x86_64 GNU/Linux
When reproducing issue, be patient , you have to wait several iterations
before it will fail.
Some bug reports and discussion related to :
https://bugs.python.org/issue41345
https://github.com/psf/requests/issues/4664
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=899406
po 20. 7. 2020 v 14:54 odesílatel Ilia Androshchuk <report@bugs.python.org>
napsal:
> Ilia Androshchuk <an7e@outlook.com> added the comment:
> Hi Michal,
> Which version of operating system and apache are you running?
> I'll try to reproduce
> ----------
> nosy: +an7e
> _______________________________________
> Python tracker <report@bugs.python.org>
> <https://bugs.python.org/issue41345>
> _______________________________________
DEBUG:urllib3.connectionpool:Resetting dropped connection: localhost
DEBUG:urllib3.connectionpool:http://localhost:80 "POST / HTTP/1.1" 200 3138
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/lib/python3.8/http/client.py", line 1332, in getresponse
    response.begin()
  File "/usr/lib/python3.8/http/client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.8/http/client.py", line 272, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 400, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/lib/python3/dist-packages/six.py", line 702, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/lib/python3.8/http/client.py", line 1332, in getresponse
    response.begin()
  File "/usr/lib/python3.8/http/client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.8/http/client.py", line 272, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "test1.py", line 14, in <module>
    s.post('http://localhost', data={counter:txt})
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
I'm using same dist and settings:
lerfi@UbuntuVM:~/work/psf/41345$ uname -a
Linux UbuntuVM 5.4.0-40-generic #44-Ubuntu SMP Tue Jun 23 00:01:04 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
erfi@UbuntuVM:~/work/psf/41345$ dpkg -l | grep apache
ii  apache2                                    2.4.41-4ubuntu3                       amd64        Apache HTTP Server
ii  apache2-bin                                2.4.41-4ubuntu3                       amd64        Apache HTTP Server (modules and other binary files)
ii  apache2-data                               2.4.41-4ubuntu3                       all          Apache HTTP Server (common files)
ii  apache2-utils                              2.4.41-4ubuntu3                       amd64        Apache HTTP Server (utility programs for web servers)
pip3 requests==2.22.0
it looks like there's a problem with this urllib3 package
Thank you very much for help, I created pull request for urllib3 -> https://github.com/urllib3/urllib3/pull/1911 Can u just confirm that this could be fixed in urllib3 as it is in pull request ? Have I fixed it by good way ? Thanks. Michal Arbet ( kevko ) pá 24. 7. 2020 v 20:29 odesílatel Guido van Rossum < report@bugs.python.org > napsal: > Guido van Rossum < guido@python.org > added the comment: > This surely is some application corner case. Closing. > ---------- > nosy: +gvanrossum > resolution: -> not a bug > stage: -> resolved > status: open -> closed > _______________________________________ > Python tracker < report@bugs.python.org > > < https://bugs.python.org/issue41345 > > _______________________________________
Previous report about Requests to the Python bug tracker: Issue 33620.
I suspect this is an unavoidable race condition with trying a POST (or other non-idempotent) request on an idle HTTP connection. I think it has to be up to the higher-level application or user to decide if it is safe to retry a POST request. Otherwise you risk e.g. accidentally ordering two pizzas because the server received two POST requests but something interfered with the response of the first response. On the other hand, I noticed some browsers seem to automatically retry a POST once if it is interrupted, which makes me uneasy.
A concrete example of the problem is a firmware upload that triggers a reboot. If the reboot is too quick and prevents the POST response being sent, I found that a web browser will repeat the firmware upload once more after my firmware boots up again.
If it is not safe to retry the POST request, other options would be to avoid the server thinking the connection is stale:
* always do the POST request on a fresh HTTP connection
* "ping" the connection with a dummy request (e.g. OPTIONS, HEAD, or GET) immediately before the POST request
Another option that comes to mind is to try using the 100 Continue mechanism, but this is not a general solution and depends on the application.
2022-04-11 14:59:33adminsetgithub: 85517 2020-07-28 05:47:14martin.pantersetnosy: + martin.panter
messages: + msg374466
2020-07-27 08:04:37Michal Arbetsetmessages: + msg374365 2020-07-24 18:28:51gvanrossumsetstatus: open -> closed

nosy: + gvanrossum
messages: + msg374200

resolution: not a bug
stage: resolved 2020-07-21 13:18:28an7esetmessages: + msg374066 2020-07-20 23:17:21an7esetmessages: + msg374034 2020-07-20 13:48:46Michal Arbetsetmessages: + msg374008 2020-07-20 12:54:48an7esetnosy: + an7e
messages: + msg374004
2020-07-20 11:43:46Michal Arbetcreate