[Python-checkins] cpython (3.2): Issue #10287: nntplib now queries the server's CAPABILITIES first before

antoine.pitrou python-checkins at python.org
Tue Feb 14 23:33:47 CET 2012


http://hg.python.org/cpython/rev/a7f1ffd741d6
changeset: 74933:a7f1ffd741d6
branch: 3.2
parent: 74930:ac362fb3b86b
user: Antoine Pitrou <solipsis at pitrou.net>
date: Tue Feb 14 23:29:34 2012 +0100
summary:
 Issue #10287: nntplib now queries the server's CAPABILITIES first before sending MODE READER, and only sends it if not already in READER mode.
Patch by Hynek Schlawack.
files:
 Lib/nntplib.py | 21 ++++++++---
 Lib/test/test_nntplib.py | 51 +++++++++++++++++++++++++++-
 Misc/NEWS | 4 ++
 3 files changed, 69 insertions(+), 7 deletions(-)
diff --git a/Lib/nntplib.py b/Lib/nntplib.py
--- a/Lib/nntplib.py
+++ b/Lib/nntplib.py
@@ -324,25 +324,30 @@
 self.debugging = 0
 self.welcome = self._getresp()
 
+ # Inquire about capabilities (RFC 3977).
+ self._caps = None
+ self.getcapabilities()
+
 # 'MODE READER' is sometimes necessary to enable 'reader' mode.
 # However, the order in which 'MODE READER' and 'AUTHINFO' need to
 # arrive differs between some NNTP servers. If _setreadermode() fails
 # with an authorization failed error, it will set this to True;
 # the login() routine will interpret that as a request to try again
 # after performing its normal function.
+ # Enable only if we're not already in READER mode anyway.
 self.readermode_afterauth = False
- if readermode:
+ if readermode and 'READER' not in self._caps:
 self._setreadermode()
+ if not self.readermode_afterauth:
+ # Capabilities might have changed after MODE READER
+ self._caps = None
+ self.getcapabilities()
 
 # RFC 4642 2.2.2: Both the client and the server MUST know if there is
 # a TLS session active. A client MUST NOT attempt to start a TLS
 # session if a TLS session is already active.
 self.tls_on = False
 
- # Inquire about capabilities (RFC 3977).
- self._caps = None
- self.getcapabilities()
-
 # Log in and encryption setup order is left to subclasses.
 self.authenticated = False
 
@@ -945,8 +950,12 @@
 self._caps = None
 self.getcapabilities()
 # Attempt to send mode reader if it was requested after login.
- if self.readermode_afterauth:
+ # Only do so if we're not in reader mode already.
+ if self.readermode_afterauth and 'READER' not in self._caps:
 self._setreadermode()
+ # Capabilities might have changed after MODE READER
+ self._caps = None
+ self.getcapabilities()
 
 def _setreadermode(self):
 try:
diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py
--- a/Lib/test/test_nntplib.py
+++ b/Lib/test/test_nntplib.py
@@ -364,6 +364,12 @@
 return self.server
 
 
+class MockedNNTPWithReaderModeMixin(MockedNNTPTestsMixin):
+ def setUp(self):
+ super().setUp()
+ self.make_server(readermode=True)
+
+
 class NNTPv1Handler:
 """A handler for RFC 977"""
 
@@ -704,6 +710,9 @@
 else:
 self.push_lit(fmt.format(''))
 
+ def handle_MODE(self, _):
+ raise Exception('MODE READER sent despite READER has been advertised')
+
 def handle_OVER(self, message_spec=None):
 return self.handle_XOVER(message_spec)
 
@@ -718,6 +727,34 @@
 super().handle_CAPABILITIES()
 
 
+class ModeSwitchingNNTPv2Handler(NNTPv2Handler):
+ """A server that starts in transit mode"""
+
+ def __init__(self):
+ self._switched = False
+
+ def handle_CAPABILITIES(self):
+ fmt = """\
+ 101 Capability list:
+ VERSION 2 3
+ IMPLEMENTATION INN 2.5.1
+ HDR
+ LIST ACTIVE ACTIVE.TIMES DISTRIB.PATS HEADERS NEWSGROUPS OVERVIEW.FMT
+ OVER
+ POST
+ {}READER
+ ."""
+ if self._switched:
+ self.push_lit(fmt.format(''))
+ else:
+ self.push_lit(fmt.format('MODE-'))
+
+ def handle_MODE(self, what):
+ assert not self._switched and what == 'reader'
+ self._switched = True
+ self.push_lit('200 Posting allowed')
+
+
 class NNTPv1v2TestsMixin:
 
 def setUp(self):
@@ -1124,6 +1161,18 @@
 self.assertIn('VERSION', self.server._caps)
 
 
+class SendReaderNNTPv2Tests(MockedNNTPWithReaderModeMixin,
+ unittest.TestCase):
+ """Same tests as for v2 but we tell NTTP to send MODE READER to a server
+ that isn't in READER mode by default."""
+
+ nntp_version = 2
+ handler_class = ModeSwitchingNNTPv2Handler
+
+ def test_we_are_in_reader_mode_after_connect(self):
+ self.assertIn('READER', self.server._caps)
+
+
 class MiscTests(unittest.TestCase):
 
 def test_decode_header(self):
@@ -1284,7 +1333,7 @@
 
 def test_main():
 tests = [MiscTests, NNTPv1Tests, NNTPv2Tests, CapsAfterLoginNNTPv2Tests,
- NetworkedNNTPTests]
+ SendReaderNNTPv2Tests, NetworkedNNTPTests]
 if _have_ssl:
 tests.append(NetworkedNNTP_SSLTests)
 support.run_unittest(*tests)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -113,6 +113,10 @@
 Library
 -------
 
+- Issue #10287: nntplib now queries the server's CAPABILITIES first before
+ sending MODE READER, and only sends it if not already in READER mode.
+ Patch by Hynek Schlawack.
+
 - Issue #13979: A bug in ctypes.util.find_library that caused
 the wrong library name to be returned has been fixed.
 
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /