Beispiel #1
0
 def test_deliver_baddata(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(
         b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n'
     )
     self.sock.recv(
         IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(
         b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'450 Yikes\r\n')
     self.sock.sendall(b'RSET\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              self.queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     with self.assertRaises(TransientRelayError):
         result.get_nowait()
 def test_run_multiple(self):
     result1 = AsyncResult()
     result2 = AsyncResult()
     env1 = Envelope('*****@*****.**', ['*****@*****.**'])
     env1.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     env2 = Envelope('*****@*****.**', ['*****@*****.**'])
     env2.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result1, env1))
     queue.append((result2, env2))
     self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test', idle_timeout=0.0)
     client._run()
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result1.get_nowait())
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result2.get_nowait())
 def test_deliver_conversion_failure(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'RSET\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     with self.assertRaises(PermanentRelayError):
         result.get_nowait()
 def test_run_banner_failure(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndReturn(b'520 Not Welcome\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test')
     client._run()
     with self.assertRaises(PermanentRelayError):
         result.get_nowait()
Beispiel #5
0
 def test_run(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(
         b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n'
     )
     self.sock.recv(
         IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(
         b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there')
     client._run()
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')},
                      result.get_nowait())
Beispiel #6
0
 def test_deliver_conversion(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(
         b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n'
     )
     self.sock.recv(
         IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     if pycompat.PY3:
         self.sock.sendall(
             b'From: [email protected]\r\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIEK\r\n.\r\n'
         )
     else:
         self.sock.sendall(
             b'From: [email protected]\r\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIENCg==\r\n.\r\n'
         )
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              self.queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there',
                              binary_encoder=encode_base64)
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')},
                      result.get_nowait())
Beispiel #7
0
 def test_deliver(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 8BITMIME\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'RCPT TO:<*****@*****.**>\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'DATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'354 Go ahead\r\n')
     self.sock.sendall(
         b'From: [email protected]\r\n\r\ntest test \x81\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              self.queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')},
                      result.get_nowait())
 def test_run_random_exception(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndRaise(ValueError('test error'))
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test')
     with self.assertRaises(ValueError):
         client._run()
     with self.assertRaises(ValueError):
         result.get_nowait()
 def test_deliver_badrcpts(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n550 Not ok\r\n354 Go ahead\r\n')
     self.sock.sendall(b'.\r\nRSET\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'550 Yikes\r\n250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     with self.assertRaises(PermanentRelayError):
         result.get_nowait()
Beispiel #10
0
 def test_run_smtperror(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndRaise(SmtpError('test error'))
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr',
                              queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='test')
     client._run()
     with self.assertRaises(TransientRelayError):
         result.get_nowait()
Beispiel #11
0
 def test_deliver_conversion_failure(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'RSET\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              self.queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     with self.assertRaises(PermanentRelayError):
         result.get_nowait()
 def test_deliver_rset_exception(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n450 No!\r\n')
     self.sock.sendall(b'RSET\r\n')
     self.sock.recv(IsA(int)).AndRaise(ConnectionLost)
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test')
     client._connect()
     client._ehlo()
     with self.assertRaises(ConnectionLost):
         client._deliver(result, env)
     with self.assertRaises(TransientRelayError):
         result.get_nowait()
Beispiel #13
0
 def test_run_banner_failure(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndReturn(b'520 Not Welcome\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0),
                              queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='there')
     client._run()
     with self.assertRaises(PermanentRelayError):
         result.get_nowait()
Beispiel #14
0
 def test_run_multiple(self):
     result1 = AsyncResult()
     result2 = AsyncResult()
     env1 = Envelope('*****@*****.**', ['*****@*****.**'])
     env1.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     env2 = Envelope('*****@*****.**', ['*****@*****.**'])
     env2.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result1, env1))
     queue.append((result2, env2))
     self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(
         b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n'
     )
     self.sock.recv(
         IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(
         b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(
         b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n'
     )
     self.sock.recv(
         IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(
         b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr',
                              queue,
                              socket_creator=self._socket_creator,
                              ehlo_as='test',
                              idle_timeout=0.0)
     client._run()
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')},
                      result1.get_nowait())
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')},
                      result2.get_nowait())
 def test_deliver_conversion(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(b'From: [email protected]\r\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIENCg==\n\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test', binary_encoder=encode_base64)
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
Beispiel #16
0
 def test_run(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test\r\n')
     queue = BlockingDeque()
     queue.append((result, env))
     self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n')
     self.sock.sendall(b'EHLO there\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n')
     self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'QUIT\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n')
     self.sock.close()
     self.mox.ReplayAll()
     client = SmtpRelayClient(('addr', 0), queue, socket_creator=self._socket_creator, ehlo_as='there')
     client._run()
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
 def test_deliver(self):
     result = AsyncResult()
     env = Envelope('*****@*****.**', ['*****@*****.**'])
     env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n')
     self.sock.sendall(b'EHLO test\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 8BITMIME\r\n')
     self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'RCPT TO:<*****@*****.**>\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.sock.sendall(b'DATA\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'354 Go ahead\r\n')
     self.sock.sendall(b'From: [email protected]\r\n\r\ntest test \x81\r\n.\r\n')
     self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n')
     self.mox.ReplayAll()
     client = SmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test')
     client._connect()
     client._ehlo()
     client._deliver(result, env)
     self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
Beispiel #18
0
class MessageChannel(Channel):
    """A channel that adds useful semantics for publishing and consuming messages.

    Semantics that are added:

    * Support for registering consumers to receive basic.deliver events.
      Consumers also receive errors and are automatically deregistered when
      basic_cancel is received.

    * Support for the RabbitMQ extension confirm_select, which makes
      basic_publish block

    * Can check for messages returned with basic_return

    """
    def __init__(self, connection, id):
        super(MessageChannel, self).__init__(connection, id)
        self.consumer_id = 1
        self.consumers = {}
        self.returned = AsyncResult()
        self.listeners.set_handler('basic.deliver', self.on_deliver)
        self.listeners.set_handler('basic.return', self.on_basic_return)
        self.listeners.set_handler('basic.cancel-ok', self.on_cancel_ok)
        self.listeners.set_handler('basic.cancel', self.on_cancel_ok)

    def on_deliver(self, message):
        """Called when a message is received.

        Dispatches the message to the registered consumer.
        """
        self.consumers[message.consumer_tag](message)

    def on_basic_return(self, msg):
        """When we receive a basic.return message, store it.

        The value can later be checked using .check_returned().

        """
        self.returned.set(msg)

    def check_returned(self):
        """Raise an error if a message has been returned.

        This also clears the returned frame, with the intention that each
        basic.return message may cause at most one MessageReturned error.

        """
        if self._method and self._method.name == 'basic.return':
            self.must_now_block()
            returned = self.returned.get()
        else:
            try:
                returned = self.returned.get_nowait()
            except gevent.Timeout:
                return

        self.clear_returned()
        if returned:
            raise exceptions.return_exception_from_frame(returned)

    def clear_returned(self):
        """Discard any returned message."""
        if self.returned.ready():
            # we can only replace returned if it is ready - otherwise anything
            # that was blocked waiting would wait forever.
            self.returned = AsyncResult()

    def on_error(self, exc):
        """Override on_error, to pass error to all consumers."""
        for consumer in self.consumers.values():
            self.queue.put((consumer, (exc, )))
        super(MessageChannel, self).on_error(exc)

    def on_cancel_ok(self, frame):
        """The server has cancelled a consumer.

        We can remove its consumer tag from the registered consumers."""
        del (self.consumers[frame.consumer_tag])

    def basic_consume(self,
                      queue='',
                      no_local=False,
                      no_ack=False,
                      exclusive=False,
                      arguments={},
                      callback=None):
        """Begin consuming messages from a queue.

        Consumers last as long as the channel they were declared on, or until
        the client cancels them.

        :param queue: Specifies the name of the queue to consume from.
        :param no_local: Do not deliver own messages. If this flag is set the
            server will not send messages to the connection that published
            them.
        :param no_ack: Don't require acknowledgements. If this flag is set the
            server does not expect acknowledgements for messages. That is, when
            a message is delivered to the client the server assumes the
            delivery will succeed and immediately dequeues it. This
            functionality may increase performance but at the cost of
            reliability. Messages can get lost if a client dies before they
            are delivered to the application.
        :param exclusive: Request exclusive consumer access, meaning only this
            consumer can access the queue.
        :param arguments: A set of arguments for the consume. The syntax and
            semantics of these arguments depends on the server implementation.
        :param callback: A callback to be called for each message received.

        """
        tag = 'ct-%d' % self.consumer_id
        self.consumer_id += 1

        kwargs = dict(queue=queue,
                      no_local=no_local,
                      no_ack=no_ack,
                      exclusive=exclusive,
                      arguments=arguments,
                      consumer_tag=tag)

        if callback is not None:
            self.consumers[tag] = callback
            return super(MessageChannel, self).basic_consume(**kwargs)
        else:
            queue = MessageQueue(self, tag)
            self.consumers[tag] = queue.put
            super(MessageChannel, self).basic_consume(**kwargs)
            return queue

    def basic_get(self, *args, **kwargs):
        """Wrap basic_get to return None if the response is basic.get-empty.

        This will be easier for users to check than testing whether a response
        is get-empty.
        """
        r = super(MessageChannel, self).basic_get(*args, **kwargs)
        return r if isinstance(r, Message) else None

    def confirm_select(self, nowait=False):
        """Turn on RabbitMQ's publisher acknowledgements.

        See http://www.rabbitmq.com/confirms.html

        There are two things that need to be done:

        * Swap basic_publish to a version that blocks waiting for the
          corresponding ack.

        * Support nowait (because this method blocks or not depending on that
          argument)

        """
        self.basic_publish = self.basic_publish_with_confirm

        if nowait:
            super(MessageChannel, self).confirm_select(nowait=nowait)
        else:
            # Send frame directly, as no callback will be received
            self._send(spec.FrameConfirmSelect(1))

    def basic_publish_with_confirm(self,
                                   exchange='',
                                   routing_key='',
                                   mandatory=False,
                                   immediate=False,
                                   headers={},
                                   body=''):
        """Version of basic publish that blocks waiting for confirm."""
        method = super(MessageChannel, self).basic_publish
        self.clear_returned()
        ret = self._call_sync(method, ('basic.ack', 'basic.nack'), exchange,
                              routing_key, mandatory, immediate, headers, body)
        if ret.name == 'basic.nack':
            raise exceptions.PublishFailed(ret)
        if mandatory or immediate:
            self.check_returned()
        return ret