[Python-checkins] [3.11] gh-81403: Fix for CacheFTPHandler in urllib (GH-13951) (#103705)

orsenthil webhook-mailer at python.org
Sun Apr 23 08:20:41 EDT 2023


https://github.com/python/cpython/commit/6e25228b2e8bd9556b879c629ee20876271bf7da
commit: 6e25228b2e8bd9556b879c629ee20876271bf7da
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: orsenthil <senthilx at amazon.com>
date: 2023-04-23T05:20:34-07:00
summary:

[3.11] gh-81403: Fix for CacheFTPHandler in urllib (GH-13951) (#103705)

* gh-81403: Fix for CacheFTPHandler in urllib (GH-13951)

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.

(cherry picked from commit e38bebb9ee805df6848f42845e71c8da8a821ad3)

Co-authored-by: Dan Hemberger <846186+hemberger at users.noreply.github.com>
Co-authored-by: Senthil Kumaran <senthil at python.org>

* Added NEWS entry.

---------

Co-authored-by: Dan Hemberger <846186+hemberger at users.noreply.github.com>
Co-authored-by: Senthil Kumaran <senthil at python.org>

files:
A Misc/NEWS.d/next/Library/2023-04-22-22-14-09.gh-issue-81403.zVz9Td.rst
M Lib/test/test_urllib2net.py
M Lib/urllib/request.py

diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py
index 5da41c37bbfb..d8d882b2d335 100644
--- a/Lib/test/test_urllib2net.py
+++ b/Lib/test/test_urllib2net.py
@@ -134,7 +134,9 @@ def setUp(self):
     # They do sometimes catch some major disasters, though.
 
     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 73ad0127ecc9..24911bb0190b 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -2469,7 +2469,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
diff --git a/Misc/NEWS.d/next/Library/2023-04-22-22-14-09.gh-issue-81403.zVz9Td.rst b/Misc/NEWS.d/next/Library/2023-04-22-22-14-09.gh-issue-81403.zVz9Td.rst
new file mode 100644
index 000000000000..6adb71f76772
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-04-22-22-14-09.gh-issue-81403.zVz9Td.rst
@@ -0,0 +1,3 @@
+:class:`urllib.request.CacheFTPHandler` no longer raises :class:`URLError`
+if a cached FTP instance is reused. ftplib's endtransfer method calls
+voidresp to drain the connection to handle FTP instance reuse properly.



More information about the Python-checkins mailing list