예제 #1
0
 def _raise_error_if_disconnected(self):
     '''
     See if we're still connected, and if not, raise an error.
     '''
     if not self.is_connected:
         # TODO: maybe SMTPConnectError here if we never were connected?
         raise SMTPServerDisconnected('Not connected to SMTP server')
예제 #2
0
    async def read_response(self):
        '''
        Get a status reponse from the server.

        Returns a tuple consisting of:

          - server response code (e.g. 250, or such, if all goes well)

          - server response string corresponding to response code (multiline
            responses are converted to a single, multiline string).

        Raises SMTPResponseException for codes > 500.
        '''
        code = None
        response_lines = []

        while True:
            try:
                line = await self.readline()
            # TODO: alternative to LimitOverrunError
            # except LimitOverrunError:
            #     raise SMTPResponseException(500, "Line too long.")
            except ConnectionResetError as exc:
                raise SMTPServerDisconnected(exc)

            try:
                code = int(line[:3])
            except ValueError:
                pass

            message = line[4:].strip(b' \t\r\n').decode('ascii')
            response_lines.append(message)

            if line[3:4] != b"-":
                break

        full_message = "\n".join(response_lines)

        if code is None and self.at_eof():
            raise SMTPServerDisconnected('Server disconnected unexpectedly')
        elif code is None:
            raise SMTPResponseException(
                -1, 'Malformed SMTP response: {}'.format(full_message))
        elif status.is_permanent_error_code(code):
            raise SMTPResponseException(code, full_message)

        return code, full_message
예제 #3
0
 def _raise_error_if_disconnected(self):
     '''
     See if we're still connected, and if not, raise an error.
     '''
     if not self.is_connected:
         message = 'Not connected to SMTP server on {}:{}'.format(
             self.hostname, self.port)
         raise SMTPServerDisconnected(message)
예제 #4
0
    async def send_command(self, *args):
        '''
        Format a command and send it to the server.
        '''
        command = '{}\r\n'.format(' '.join(args)).encode('ascii')
        self.write(command)

        try:
            await self.drain()
        except ConnectionResetError as exc:
            raise SMTPServerDisconnected(exc)
예제 #5
0
    async def start_tls(self, context, server_hostname=None):
        try:
            await self.drain()
        except ConnectionResetError as exc:
            raise SMTPServerDisconnected(exc)

        waiter = asyncio.Future(loop=self._loop)

        tls_protocol = self._protocol.start_tls(
            context, server_hostname=server_hostname, waiter=waiter)

        self._transport = tls_protocol._app_transport

        await waiter

        return tls_protocol, tls_protocol._app_transport