11##
2- # copyright 2009, James William Pye
3- # http://python.projects.postgresql.org
2+ # .python.socket - additional tools for working with sockets
43##
5- """
6- socket tools
7- """
84import sys
5+ import os
96import random
107import socket
118import math
@@ -23,46 +20,38 @@ class SocketFactory(object):
2320 Additionally, it provides methods and attributes for abstracting
2421 exception management on socket operation.
2522 """
26- fatal_exception_messages = {
27- errno .ECONNRESET : 'server explicitly closed the connection' ,
28- errno .EPIPE : 'broken connection detected on send' ,
29- errno .ECONNREFUSED : 'server refused connection' ,
30- errno .EHOSTUNREACH : 'server is not reachable' ,
31- errno .EBADF : 'bad file descriptor' ,
32- }
33- if sys .platform in ('win32' , 'win64' ):
34- fatal_exception_messages .update ({
35- errno .WSAECONNABORTED : 'server aborted the connection' ,
36- })
3723
3824 timeout_exception = socket .timeout
3925 fatal_exception = socket .error
4026 try_again_exception = socket .error
4127
4228 def timed_out (self , err ) -> bool :
43- return type ( err ) is self .timeout_exception
29+ return err . __class__ is self .timeout_exception
4430
45- def try_again (self , err ) -> bool :
31+ @staticmethod
32+ def try_again (err , codes = (errno .EAGAIN , errno .EINTR , errno .EWOULDBLOCK , errno .ETIMEDOUT )) -> bool :
4633 """
47- Does the error indicate that the operation should be
48- tried again?
49- """
50- return getattr (err , 'errno' , 0 ) == errno .EINTR
34+ Does the error indicate that the operation should be tried again?
5135
52- def connection_refused (self , err ) -> bool :
53- """
54- Does the error indicate that the connection was explicitly
55- refused by the server?
36+ More importantly, the connection is *not* dead.
5637 """
57- return getattr (err , 'errno' , 0 ) == errno .ECONNREFUSED
38+ errno = getattr (err , 'errno' , None )
39+ if errno is None :
40+ return False
41+ return errno in codes
5842
5943 @classmethod
6044 def fatal_exception_message (typ , err ) -> (str , None ):
6145 """
6246 If the exception was fatal to the connection,
6347 what message should be given to the user?
6448 """
65- return typ .fatal_exception_messages .get (err .errno )
49+ if typ .try_again (err ):
50+ return None
51+ strerr = getattr (err , 'strerror' , None )
52+ if strerr is not None :
53+ return str (strerr )
54+ return os .strerror (err .errno )
6655
6756 def secure (self , socket : socket .socket ) -> ssl .SSLSocket :
6857 "secure a socket with SSL"
0 commit comments