@@ -293,7 +293,7 @@ def _encrypt_on(sock, context, hostname):
293
293
294
294
295
295
# The classes themselves
296
- class _NNTPBase :
296
+ class NNTP :
297
297
# UTF-8 is the character set for all NNTP commands and responses: they
298
298
# are automatically encoded (when sending) and decoded (and receiving)
299
299
# by this class.
@@ -309,13 +309,18 @@ class _NNTPBase:
309
309
encoding = 'utf-8'
310
310
errors = 'surrogateescape'
311
311
312
- def __init__ (self , file , host ,
313
- readermode = None , timeout = _GLOBAL_DEFAULT_TIMEOUT ):
312
+ def __init__ (self , host , port = NNTP_PORT , user = None , password = None ,
313
+ readermode = None , usenetrc = False ,
314
+ timeout = _GLOBAL_DEFAULT_TIMEOUT ):
314
315
"""Initialize an instance. Arguments:
315
- - file: file-like object (open for read/write in binary mode)
316
- - host: hostname of the server
316
+ - host: hostname to connect to
317
+ - port: port to connect to (default the standard NNTP port)
318
+ - user: username to authenticate with
319
+ - password: password to use with username
317
320
- readermode: if true, send 'mode reader' command after
318
321
connecting.
322
+ - usenetrc: allow loading username and password from ~/.netrc file
323
+ if not specified explicitly
319
324
- timeout: timeout (in seconds) used for socket connections
320
325
321
326
readermode is sometimes necessary if you are connecting to an
@@ -325,7 +330,24 @@ def __init__(self, file, host,
325
330
readermode.
326
331
"""
327
332
self .host = host
328
- self .file = file
333
+ self .port = port
334
+ self .sock = self ._create_socket (timeout )
335
+ self .file = None
336
+ try :
337
+ self .file = self .sock .makefile ("rwb" )
338
+ self ._base_init (readermode )
339
+ if user or usenetrc :
340
+ self .login (user , password , usenetrc )
341
+ except :
342
+ if self .file :
343
+ self .file .close ()
344
+ self .sock .close ()
345
+ raise
346
+
347
+ def _base_init (self , readermode ):
348
+ """Partial initialization for the NNTP protocol.
349
+ This instance method is extracted for supporting the test code.
350
+ """
329
351
self .debugging = 0
330
352
self .welcome = self ._getresp ()
331
353
@@ -370,6 +392,12 @@ def __exit__(self, *args):
370
392
if is_connected ():
371
393
self ._close ()
372
394
395
+ def _create_socket (self , timeout ):
396
+ if timeout is not None and not timeout :
397
+ raise ValueError ('Non-blocking socket (timeout=0) is not supported' )
398
+ sys .audit ("nntplib.connect" , self , self .host , self .port )
399
+ return socket .create_connection ((self .host , self .port ), timeout )
400
+
373
401
def getwelcome (self ):
374
402
"""Get the welcome message from the server
375
403
(this is read and squirreled away by __init__()).
@@ -888,8 +916,12 @@ def ihave(self, message_id, data):
888
916
return self ._post ('IHAVE {0}' .format (message_id ), data )
889
917
890
918
def _close (self ):
891
- self .file .close ()
892
- del self .file
919
+ try :
920
+ if self .file :
921
+ self .file .close ()
922
+ del self .file
923
+ finally :
924
+ self .sock .close ()
893
925
894
926
def quit (self ):
895
927
"""Process a QUIT command and close the socket. Returns:
@@ -979,56 +1011,6 @@ def starttls(self, context=None):
979
1011
raise NNTPError ("TLS failed to start." )
980
1012
981
1013
982
- class NNTP (_NNTPBase ):
983
-
984
- def __init__ (self , host , port = NNTP_PORT , user = None , password = None ,
985
- readermode = None , usenetrc = False ,
986
- timeout = _GLOBAL_DEFAULT_TIMEOUT ):
987
- """Initialize an instance. Arguments:
988
- - host: hostname to connect to
989
- - port: port to connect to (default the standard NNTP port)
990
- - user: username to authenticate with
991
- - password: password to use with username
992
- - readermode: if true, send 'mode reader' command after
993
- connecting.
994
- - usenetrc: allow loading username and password from ~/.netrc file
995
- if not specified explicitly
996
- - timeout: timeout (in seconds) used for socket connections
997
-
998
- readermode is sometimes necessary if you are connecting to an
999
- NNTP server on the local machine and intend to call
1000
- reader-specific commands, such as `group'. If you get
1001
- unexpected NNTPPermanentErrors, you might need to set
1002
- readermode.
1003
- """
1004
- self .host = host
1005
- self .port = port
1006
- self .sock = self ._create_socket (timeout )
1007
- file = None
1008
- try :
1009
- file = self .sock .makefile ("rwb" )
1010
- super ().__init__ (file , host , readermode , timeout )
1011
- if user or usenetrc :
1012
- self .login (user , password , usenetrc )
1013
- except :
1014
- if file :
1015
- file .close ()
1016
- self .sock .close ()
1017
- raise
1018
-
1019
- def _create_socket (self , timeout ):
1020
- if timeout is not None and not timeout :
1021
- raise ValueError ('Non-blocking socket (timeout=0) is not supported' )
1022
- sys .audit ("nntplib.connect" , self , self .host , self .port )
1023
- return socket .create_connection ((self .host , self .port ), timeout )
1024
-
1025
- def _close (self ):
1026
- try :
1027
- super ()._close ()
1028
- finally :
1029
- self .sock .close ()
1030
-
1031
-
1032
1014
if _have_ssl :
1033
1015
class NNTP_SSL (NNTP ):
1034
1016
0 commit comments