title: Python 3 SMTP aiosmtpd proxy/relay
body: <p>I am trying to make an open SMTP relay using the new <code>aiosmtpd</code> library that replaces <code>smtpd</code>. The program below instantiates a <code>Proxy</code> handler that is passed onto the mail controller, which is started afterwards in the background. A message is then created with a standard <code>smtplib</code> client that connects to the relay.</p>
  
  <p>All is good until the SMTP conversation between the client and the relay ends with the message never leaving the relay. The relay never replies with a <code>250 OK\r\n</code> and a <code>ctrl+c</code> shows that <code>sendmail</code> is waiting for a reply.</p>
  
  <p>Any ideas? Is the script missing something?</p>
  
  <p><strong>Edit</strong>: <code>mail.example.com</code> is only an example server. An <code>smtpd DebuggingServer</code> prints nothing upon execution of the script with <code>relay = aiosmtpd.handlers.Proxy("localhost", 1025)</code>.</p>
  
  <pre><code>$ python3.6 -m smtpd -n -c DebuggingServer -d localhost:1025
  DebuggingServer started at Fri Apr  7 18:41:09 2017
      Local addr: ('localhost', 1025)
      Remote addr:('localhost', 25)
  ...nothing printed out...
  </code></pre>
  
  <p>Script:</p>
  
  <pre><code>from aiosmtpd.handlers import Debugging, Proxy
  from aiosmtpd.controller import Controller
  from smtplib import SMTP
  
  # relay = aiosmtpd.handlers.Debugging()
  relay = aiosmtpd.handlers.Proxy("localhost", 1025)
  # relay = aiosmtpd.handlers.Proxy("mail.example.com", 25)
  controller = Controller(relay)
  controller.start()
  print(controller, controller.hostname, controller.port)
  
  input("ready... press enter to continue")
  
  print("creating SMTP with debug")
  client = SMTP()
  client.set_debuglevel(1)
  print("connecting to the SMTP server")
  client.connect(controller.hostname, controller.port)
  
  print("sending message")
  client.sendmail('alice@example.com',
                  ['bob@example.com'], """\
  From: Alice &lt;alice@example.com&gt;
  To: Bob &lt;bob@example.com&gt;
  Subject: Title
  
  Body.
  """)
  
  print("stopping controller")
  controller.stop()
  print("checking if controller really stopped")
  client.connect(controller.hostname, controller.port)
  </code></pre>
  
  <p>Here is the output of the script:</p>
  
  <pre><code> $ python3.6 relay.py
  &lt;aiosmtpd.controller.Controller object at 0x10199f710&gt; ::0 8025
  ready... press enter to continue
  creating SMTP with debug
  connecting to the SMTP server
  connect: ('::0', 8025)
  connect: to ('::0', 8025) None
  reply: b'220 localhost Python SMTP 1.0a4\r\n'
  reply: retcode (220); Msg: b'localhost Python SMTP 1.0a4'
  connect: b'localhost Python SMTP 1.0a4'
  sending message
  send: 'ehlo localhost\r\n'
  reply: b'250-localhost\r\n'
  reply: b'250-SIZE 33554432\r\n'
  reply: b'250-8BITMIME\r\n'
  reply: b'250 HELP\r\n'
  reply: retcode (250); Msg: b'localhost\nSIZE 33554432\n8BITMIME\nHELP'
  send: 'mail FROM:&lt;alice@example.com&gt; size=85\r\n'
  reply: b'250 OK\r\n'
  reply: retcode (250); Msg: b'OK'
  send: 'rcpt TO:&lt;bob@example.com&gt;\r\n'
  reply: b'250 OK\r\n'
  reply: retcode (250); Msg: b'OK'
  send: 'data\r\n'
  reply: b'354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;\r\n'
  reply: retcode (354); Msg: b'End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;'
  data: (354, b'End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;')
  send: b'From: Alice &lt;alice@example.com&gt;\r\nTo: Bob &lt;bob@example.com&gt;\r\nSubject: Title\r\n\r\nBody.\r\n.\r\n'
  
  ...nothing happens at this point...
  
  ^CTraceback (most recent call last):
    File "relay.py", line 49, in &lt;module&gt;
      """)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 881, in sendmail
      (code, resp) = self.data(msg)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 568, in data
      (code, msg) = self.getreply()
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 386, in getreply
      line = self.file.readline(_MAXLINE + 1)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 586, in readinto
      return self._sock.recv_into(b)
  KeyboardInterrupt
  </code></pre>
  
  <p>For comparison, here is the output using the debug handler:</p>
  
  <pre><code> $ python3.6 relay.py
  &lt;aiosmtpd.controller.Controller object at 0x10189f710&gt; ::0 8025
  ready... press enter to continue
  creating SMTP with debug
  connecting to the SMTP server
  connect: ('::0', 8025)
  connect: to ('::0', 8025) None
  reply: b'220 localhost Python SMTP 1.0a4\r\n'
  reply: retcode (220); Msg: b'localhost Python SMTP 1.0a4'
  connect: b'localhost Python SMTP 1.0a4'
  sending message
  send: 'ehlo localhost\r\n'
  reply: b'250-localhost\r\n'
  reply: b'250-SIZE 33554432\r\n'
  reply: b'250-8BITMIME\r\n'
  reply: b'250 HELP\r\n'
  reply: retcode (250); Msg: b'localhost\nSIZE 33554432\n8BITMIME\nHELP'
  send: 'mail FROM:&lt;alice@example.com&gt; size=85\r\n'
  reply: b'250 OK\r\n'
  reply: retcode (250); Msg: b'OK'
  send: 'rcpt TO:&lt;bob@example.com&gt;\r\n'
  reply: b'250 OK\r\n'
  reply: retcode (250); Msg: b'OK'
  send: 'data\r\n'
  reply: b'354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;\r\n'
  reply: retcode (354); Msg: b'End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;'
  data: (354, b'End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;')
  send: b'From: Alice &lt;alice@example.com&gt;\r\nTo: Bob &lt;bob@example.com&gt;\r\nSubject: Title\r\n\r\nBody.\r\n.\r\n'
  ---------- MESSAGE FOLLOWS ----------
  mail options: ['SIZE=85']
  rcpt options: []
  
  From: Alice &lt;alice@example.com&gt;
  To: Bob &lt;bob@example.com&gt;
  Subject: Title
  X-Peer: ('::1', 64397, 0, 0)
  
  Body.
  ------------ END MESSAGE ------------
  reply: b'250 OK\r\n'
  reply: retcode (250); Msg: b'OK'
  data: (250, b'OK')
  stopping controller
  checking if controller really stopped
  connect: ('::0', 8025)
  connect: to ('::0', 8025) None
  Traceback (most recent call last):
    File "relay.py", line 51, in &lt;module&gt;
      client.connect(controller.hostname, controller.port)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 335, in connect
      self.sock = self._get_socket(host, port, self.timeout)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 306, in _get_socket
      self.source_address)
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 722, in create_connection
      raise err
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection
      sock.connect(sa)
  ConnectionRefusedError: [Errno 61] Connection refused
  </code></pre>