예제 #1
0
    def __init__(self, sender=None, recipients=None,
                 headers=None, message=None):
        #: Sending address of the message.
        self.sender = sender

        #: List of recipient addresses of the message.
        self.recipients = recipients or []

        #: :class:`email.message.Message` object for accessing and modifying
        #: message headers.
        self.headers = headers

        #: String of message data, not including headers.
        check_argtype(message, bytes, 'message', or_none=True)
        self.message = message

        #: Dictionary of information about the client that sent the message.
        #: Utilized keys include:
        #:
        #: - ``ip``: The IP of the client.
        #: - ``host``: The reverse-lookup of the client IP.
        #: - ``name``: The client name, as given by its ``EHLO`` or
        #:             alternative.
        #: - ``protocol``: The protocol used by the client, generally a variant
        #:                 of ``"SMTP"``.
        #: - ``auth``: The name the client successfully authenticated with, or
        #:             ``None``.
        self.client = {}

        #: Hostname of the :mod:`slimta` server that received the message.
        self.receiver = None

        #: Timestamp when the message was received.
        self.timestamp = None
예제 #2
0
    def __init__(self, sender=None, recipients=None,
                 headers=None, message=None):
        #: Sending address of the message.
        self.sender = sender

        #: List of recipient addresses of the message.
        self.recipients = recipients or []

        #: :class:`email.message.Message` object for accessing and modifying
        #: message headers.
        self.headers = headers

        #: String of message data, not including headers.
        check_argtype(message, bytes, 'message', or_none=True)
        self.message = message

        #: Dictionary of information about the client that sent the message.
        #: Utilized keys include:
        #:
        #: - ``ip``: The IP of the client.
        #: - ``host``: The reverse-lookup of the client IP.
        #: - ``name``: The client name, as given by its ``EHLO`` or
        #:             alternative.
        #: - ``protocol``: The protocol used by the client, generally a variant
        #:                 of ``"SMTP"``.
        #: - ``auth``: The name the client successfully authenticated with, or
        #:             ``None``.
        self.client = {}

        #: Hostname of the :mod:`slimta` server that received the message.
        self.receiver = None

        #: Timestamp when the message was received.
        self.timestamp = None
예제 #3
0
 def raw_send(self, data):
     check_argtype(data, six.binary_type, 'data')
     try:
         self.socket.sendall(data)
     except socket_error as e:
         if e.errno == ECONNRESET:
             raise ConnectionLost()
         raise
     log.send(self.socket, data)
예제 #4
0
 def _process_part(self, part):
     """
     :type part: bytes
     """
     check_argtype(part, six.binary_type, 'part')
     part_len = len(part)
     i = 0
     if part_len > 0 and part[0:1] == b'.':
         yield b'.'
     while i < part_len:
         index = part.find(b'\n.', i)
         if index == -1:
             yield part if i == 0 else part[i:]
             i = part_len
         else:
             yield part[i:index + 2]
             yield b'.'
             i = index + 2
예제 #5
0
 def _process_part(self, part):
     """
     :type part: bytes
     """
     check_argtype(part, six.binary_type, 'part')
     part_len = len(part)
     i = 0
     if part_len > 0 and part[0:1] == b'.':
         yield b'.'
     while i < part_len:
         index = part.find(b'\n.', i)
         if index == -1:
             yield part if i == 0 else part[i:]
             i = part_len
         else:
             yield part[i:index+2]
             yield b'.'
             i = index+2
예제 #6
0
    def __init__(self, code=None, message=None, command=None):
        self.command = command

        #: Holds the reply code, which can only be set to a string containing
        #: three digits.
        check_argtype(code, six.string_types, 'code', or_none=True)
        self.code = code

        #: Holds the ENHANCEDSTATUSCODES_ string. This property is usually set
        #: automatically by the ``message`` property.
        self.enhanced_status_code = None

        #: Gets and sets the reply message. If you set this property with an
        #: ENHANCEDSTATUSCODES_ string prefixed, that string will be pulled out
        #: and set in the ``enhanced_status_code``.
        check_argtype(message, six.string_types, 'message', or_none=True)
        self.message = message

        #: Boolean defining whether a newline should be sent before the reply,
        #: which is useful for asynchronous replies such as timeouts.
        self.newline_first = False
예제 #7
0
    def __init__(self, code=None, message=None, command=None):
        self.command = command

        #: Holds the reply code, which can only be set to a string containing
        #: three digits.
        check_argtype(code, six.string_types, 'code', or_none=True)
        self.code = code

        #: Holds the ENHANCEDSTATUSCODES_ string. This property is usually set
        #: automatically by the ``message`` property.
        self.enhanced_status_code = None

        #: Gets and sets the reply message. If you set this property with an
        #: ENHANCEDSTATUSCODES_ string prefixed, that string will be pulled out
        #: and set in the ``enhanced_status_code``.
        check_argtype(message, six.string_types, 'message', or_none=True)
        self.message = message

        #: Boolean defining whether a newline should be sent before the reply,
        #: which is useful for asynchronous replies such as timeouts.
        self.newline_first = False
예제 #8
0
    def parse(self, data):
        """Parses the given string to populate the :attr:`headers` and
        :attr:`message` attributes.

        :param data: The complete message, headers and message body.
        :type data: :py:obj:`bytes`

        """
        check_argtype(data, bytes, 'data')

        match = re.search(_HEADER_BOUNDARY, data)
        if not match:
            header_data = data
            payload = b''
        else:
            header_data = data[:match.end(0)]
            payload = data[match.end(0):]

        header_data_decoded = utf8only_decode(header_data)
        self.headers = Parser().parsestr(header_data_decoded, True)
        self.message = self.headers.get_payload().encode('ascii') + payload
        self.headers.set_payload('')
예제 #9
0
    def parse(self, data):
        """Parses the given string to populate the :attr:`headers` and
        :attr:`message` attributes.

        :param data: The complete message, headers and message body.
        :type data: :py:obj:`bytes`

        """
        check_argtype(data, bytes, 'data')

        match = re.search(_HEADER_BOUNDARY, data)
        if not match:
            header_data = data
            payload = b''
        else:
            header_data = data[:match.end(0)]
            payload = data[match.end(0):]

        header_data_decoded = utf8only_decode(header_data)
        self.headers = Parser().parsestr(header_data_decoded, True)
        self.message = self.headers.get_payload().encode('ascii') + payload
        self.headers.set_payload('')