components/python/python26/patches/Python26-23-none-on-connect.patch
changeset 470 fda4329d05f4
child 841 1a62cefa636d
equal deleted inserted replaced
469:e2dbd149ee50 470:fda4329d05f4
       
     1 --- Python-2.6.4/Lib/smtpd.py	Thu Aug  4 09:36:51 2011
       
     2 +++ Python-2.6.4/Lib/new.smtpd.py	Thu Aug  4 09:51:49 2011
       
     3 @@ -121,7 +121,15 @@
       
     4          self.__rcpttos = []
       
     5          self.__data = ''
       
     6          self.__fqdn = socket.getfqdn()
       
     7 -        self.__peer = conn.getpeername()
       
     8 +        try:
       
     9 +            self.__peer = conn.getpeername()
       
    10 +        except socket.error as err:
       
    11 +            # a race condition  may occur if the other end is closing
       
    12 +            # before we can get the peername
       
    13 +            self.close()
       
    14 +            if err.args[0] != errno.ENOTCONN:
       
    15 +                raise
       
    16 +            return
       
    17          print >> DEBUGSTREAM, 'Peer:', repr(self.__peer)
       
    18          self.push('220 %s %s' % (self.__fqdn, __version__))
       
    19          self.set_terminator('\r\n')
       
    20 @@ -285,9 +293,11 @@
       
    21              localaddr, remoteaddr)
       
    22  
       
    23      def handle_accept(self):
       
    24 -        conn, addr = self.accept()
       
    25 -        print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
       
    26 -        channel = SMTPChannel(self, conn, addr)
       
    27 +        pair = self.accept()
       
    28 +        if pair is not None:
       
    29 +            conn, addr = pair
       
    30 +            print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
       
    31 +            channel = SMTPChannel(self, conn, addr)
       
    32  
       
    33      # API for "doing something useful with the message"
       
    34      def process_message(self, peer, mailfrom, rcpttos, data):
       
    35 --- Python-2.6.4/Lib/asyncore.py	Wed Apr 15 16:00:41 2009
       
    36 +++ Python-2.6.4/Lib/new.asyncore.py	Thu Aug  4 09:55:22 2011
       
    37 @@ -340,12 +340,15 @@
       
    38          # XXX can return either an address pair or None
       
    39          try:
       
    40              conn, addr = self.socket.accept()
       
    41 -            return conn, addr
       
    42 -        except socket.error, why:
       
    43 -            if why.args[0] == EWOULDBLOCK:
       
    44 -                pass
       
    45 +        except TypeError:
       
    46 +            return None
       
    47 +        except socket.error as why:
       
    48 +            if why.args[0] in (EWOULDBLOCK, ECONNABORTED):
       
    49 +                return None
       
    50              else:
       
    51                  raise
       
    52 +        else:
       
    53 +            return conn, addr
       
    54  
       
    55      def send(self, data):
       
    56          try:
       
    57 --- Python-2.6.4/Doc/library/asyncore.rst	Wed Apr 15 16:00:41 2009
       
    58 +++ Python-2.6.4/Doc/library/new.asyncore.rst	Thu Aug  4 10:05:40 2011
       
    59 @@ -210,10 +210,13 @@
       
    60     .. method:: accept()
       
    61  
       
    62        Accept a connection.  The socket must be bound to an address and listening
       
    63 -      for connections.  The return value is a pair ``(conn, address)`` where
       
    64 -      *conn* is a *new* socket object usable to send and receive data on the
       
    65 -      connection, and *address* is the address bound to the socket on the other
       
    66 -      end of the connection.
       
    67 +      for connections.  The return value can be either ``None`` or a pair
       
    68 +      ``(conn, address)`` where *conn* is a *new* socket object usable to send
       
    69 +      and receive data on the connection, and *address* is the address bound to
       
    70 +      the socket on the other end of the connection.
       
    71 +      When ``None`` is returned it means the connection didn't take place, in
       
    72 +      which case the server should just ignore this event and keep listening
       
    73 +      for further incoming connections.
       
    74  
       
    75  
       
    76     .. method:: close()
       
    77 @@ -223,6 +226,12 @@
       
    78        flushed).  Sockets are automatically closed when they are
       
    79        garbage-collected.
       
    80  
       
    81 +.. class:: dispatcher_with_send()
       
    82 +
       
    83 +   A :class:`dispatcher` subclass which adds simple buffered output capability,
       
    84 +   useful for simple clients. For more sophisticated usage use
       
    85 +   :class:`asynchat.async_chat`.
       
    86 +
       
    87  .. class:: file_dispatcher()
       
    88  
       
    89     A file_dispatcher takes a file descriptor or file object along with an
       
    90 @@ -239,7 +248,7 @@
       
    91     socket for use by the :class:`file_dispatcher` class.  Availability: UNIX.
       
    92  
       
    93  
       
    94 -.. _asyncore-example:
       
    95 +.. _asyncore-example-1:
       
    96  
       
    97  asyncore Example basic HTTP client
       
    98  ----------------------------------
       
    99 @@ -249,7 +258,7 @@
       
   100  
       
   101     import asyncore, socket
       
   102  
       
   103 -   class http_client(asyncore.dispatcher):
       
   104 +   class HTTPClient(asyncore.dispatcher):
       
   105  
       
   106         def __init__(self, host, path):
       
   107             asyncore.dispatcher.__init__(self)
       
   108 @@ -273,6 +282,45 @@
       
   109             sent = self.send(self.buffer)
       
   110             self.buffer = self.buffer[sent:]
       
   111  
       
   112 -   c = http_client('www.python.org', '/')
       
   113  
       
   114 +   client = HTTPClient('www.python.org', '/')
       
   115     asyncore.loop()
       
   116 +
       
   117 +.. _asyncore-example-2:
       
   118 +
       
   119 +asyncore Example basic echo server
       
   120 +----------------------------------
       
   121 +
       
   122 +Here is abasic echo server that uses the :class:`dispatcher` class to accept
       
   123 +connections and dispatches the incoming connections to a handler::
       
   124 +
       
   125 +    import asyncore
       
   126 +    import socket
       
   127 +
       
   128 +    class EchoHandler(asyncore.dispatcher_with_send):
       
   129 +
       
   130 +        def handle_read(self):
       
   131 +            data = self.recv(8192)
       
   132 +            self.send(data)
       
   133 +
       
   134 +    class EchoServer(asyncore.dispatcher):
       
   135 +
       
   136 +        def __init__(self, host, port):
       
   137 +            asyncore.dispatcher.__init__(self)
       
   138 +            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
       
   139 +            self.set_reuse_addr()
       
   140 +            self.bind((host, port))
       
   141 +            self.listen(5)
       
   142 +
       
   143 +        def handle_accept(self):
       
   144 +            pair = self.accept()
       
   145 +            if pair is None:
       
   146 +                pass
       
   147 +            else:
       
   148 +                sock, addr = pair
       
   149 +                print 'Incoming connection from %s' % repr(addr)
       
   150 +                handler = EchoHandler(sock)
       
   151 +
       
   152 +    server = EchoServer('localhost', 8080)
       
   153 +    asyncore.loop()
       
   154 +