From 571f96629cd10234e8020e4d22ecef8bc3c32dba Mon Sep 17 00:00:00 2001 From: Dan Hemberger Date: Mon, 10 Jun 2019 16:29:41 -0700 Subject: [PATCH] bpo-37222: Fix for CacheFTPHandler in urllib A call to FTP.ntransfercmd must be followed by FTP.voidresp to clear the "end transfer" message. Without this, the client and server get out of sync, which will result in an error if the FTP instance is reused to open a second URL. This scenario occurs for even the most basic usage of CacheFTPHandler. Reverts the patch merged as a resolution to bpo-16270 and adds a test case for the CacheFTPHandler in test_urllib2net.py. --- Lib/test/test_urllib2net.py | 2 ++ Lib/urllib/request.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index 0f43d71ea67b55..007681fd4e3a36 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -104,7 +104,9 @@ def setUp(self): @skip_ftp_test_on_travis def test_ftp(self): + # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ + 'ftp://www.pythontest.net/README', 'ftp://www.pythontest.net/README', ('ftp://www.pythontest.net/non-existent-file', None, urllib.error.URLError), diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index f6ce9cb6d5866e..b85a9b60d74870 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -2432,7 +2432,13 @@ def retrfile(self, file, type): return (ftpobj, retrlen) def endtransfer(self): + if not self.busy: + return self.busy = 0 + try: + self.ftp.voidresp() + except ftperrors(): + pass def close(self): self.keepalive = False