def _send_start_ok(self, frame_in): """Send Start OK frame. :param commands.Connection.Start frame_in: Amqp frame. :return: """ mechanisms = try_utf8_decode(frame_in.mechanisms) if 'EXTERNAL' in mechanisms: mechanism = 'EXTERNAL' credentials = '\0\0' elif 'PLAIN' in mechanisms: mechanism = 'PLAIN' credentials = self._plain_credentials() else: exception = AMQPConnectionError( 'Unsupported Security Mechanism(s): %s' % frame_in.mechanisms ) self._connection.exceptions.append(exception) return start_ok_frame = commands.Connection.StartOk( mechanism=mechanism, client_properties=self._client_properties(), response=credentials, locale=LOCALE ) self._write_frame(start_ok_frame)
def on_frame(self, frame_in): """Handle frame sent to channel 0. :param frame_in: Amqp frame. :return: """ LOGGER.debug('Frame Received: %s', frame_in.name) if frame_in.name == 'Heartbeat': self._connection.heartbeat.register_heartbeat() self._write_frame(Heartbeat()) elif frame_in.name == 'Connection.Start': self.server_properties = frame_in.server_properties self._send_start_ok_frame(frame_in) elif frame_in.name == 'Connection.Tune': self._send_tune_ok_frame() self._send_open_connection() elif frame_in.name == 'Connection.OpenOk': self._set_connection_state(Stateful.OPEN) elif frame_in.name == 'Connection.Close': self._close_connection(frame_in) elif frame_in.name == 'Connection.CloseOk': self._close_connection_ok() elif frame_in.name == 'Connection.Blocked': self.is_blocked = True LOGGER.warning('Connection is blocked by remote server: %s', try_utf8_decode(frame_in.reason)) elif frame_in.name == 'Connection.Unblocked': self.is_blocked = False LOGGER.info('Connection is no longer blocked by remote server') else: LOGGER.error('[Channel0] Unhandled Frame: %s', frame_in.name)
def _try_decode_dict_content(self, content): """Decode content of a dictionary. :param dict content: :return: """ result = dict() for key, value in content.items(): key = try_utf8_decode(key) if isinstance(value, dict): result[key] = self._try_decode_dict_content(value) elif isinstance(value, list): result[key] = self._try_decode_list_content(value) else: result[key] = try_utf8_decode(value) return result
def _close_channel(self, frame_in): """Close Channel. :param specification.Channel.Close frame_in: Channel Close frame. :return: """ if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = ( 'Channel %d was closed by remote server: %s' % ( self._channel_id, reply_text ) ) exception = AMQPChannelError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception) self.set_state(self.CLOSED) if self._connection.is_open: try: self._connection.write_frame( self.channel_id, specification.Channel.CloseOk() ) except AMQPConnectionError: pass self.close()
def _send_start_ok(self, frame_in): """Send Start OK frame. :param specification.Connection.Start frame_in: Amqp frame. :return: """ mechanisms = try_utf8_decode(frame_in.mechanisms) if 'EXTERNAL' in mechanisms: mechanism = 'EXTERNAL' credentials = '\0\0' elif 'PLAIN' in mechanisms: mechanism = 'PLAIN' credentials = self._plain_credentials() else: exception = AMQPConnectionError( 'Unsupported Security Mechanism(s): %s' % frame_in.mechanisms ) self._connection.exceptions.append(exception) return start_ok_frame = specification.Connection.StartOk( mechanism=mechanism, client_properties=self._client_properties(), response=credentials, locale=LOCALE ) self._write_frame(start_ok_frame)
def on_frame(self, frame_in): """Handle frame sent to this specific channel. :param pamqp.Frame frame_in: Amqp frame. :return: """ if self.rpc.on_frame(frame_in): return if frame_in.name in CONTENT_FRAME: self._inbound.append(frame_in) elif frame_in.name == 'Basic.ConsumeOk': self.add_consumer_tag(frame_in['consumer_tag']) elif frame_in.name == 'Channel.Close': self._close_channel(frame_in) elif frame_in.name == 'Basic.Cancel': LOGGER.warning('Received Basic.Cancel on consumer_tag: %s', try_utf8_decode(frame_in.consumer_tag)) self.remove_consumer_tag(frame_in.consumer_tag) elif frame_in.name == 'Basic.CancelOk': self.remove_consumer_tag(frame_in.consumer_tag) elif frame_in.name == 'Channel.Flow': self.write_frame(pamqp_spec.Channel.FlowOk(frame_in.active)) elif frame_in.name == 'Basic.Return': self._basic_return(frame_in) else: LOGGER.error('[Channel%d] Unhandled Frame: %s -- %s', self.channel_id, frame_in.name, dict(frame_in))
def _blocked_connection(self, frame_in): """Connection is Blocked. :param frame_in: :return: """ self.is_blocked = True LOGGER.warning('Connection is blocked by remote server: %s', try_utf8_decode(frame_in.reason))
def _try_decode_dict(self, content): """Decode content of a dictionary. :param dict content: :return: """ result = dict() for key, value in content.items(): key = try_utf8_decode(key) if isinstance(value, dict): result[key] = self._try_decode_dict(value) elif isinstance(value, list): result[key] = self._try_decode_list(value) elif isinstance(value, tuple): result[key] = self._try_decode_tuple(value) else: result[key] = try_utf8_decode(value) return result
def _basic_cancel(self, frame_in): """Handle a Basic Cancel frame. :param specification.Basic.Cancel frame_in: Amqp frame. :return: """ LOGGER.warning('Received Basic.Cancel on consumer_tag: %s', try_utf8_decode(frame_in.consumer_tag)) self.remove_consumer_tag(frame_in.consumer_tag)
def _try_decode_list(content): """Decode content of a list. :param list|tuple content: :return: """ result = list() for value in content: result.append(try_utf8_decode(value)) return result
def _try_decode_list_content(content): """Decode content of a list. :param list content: :return: """ result = list() for value in content: result.append(try_utf8_decode(value)) return result
def _blocked_connection(self, frame_in): """Connection is Blocked. :param frame_in: :return: """ self.is_blocked = True LOGGER.warning( 'Connection is blocked by remote server: %s', try_utf8_decode(frame_in.reason) )
def _basic_cancel(self, frame_in): """Handle a Basic Cancel frame. :param specification.Basic.Cancel frame_in: Amqp frame. :return: """ LOGGER.warning( 'Received Basic.Cancel on consumer_tag: %s', try_utf8_decode(frame_in.consumer_tag) ) self.remove_consumer_tag(frame_in.consumer_tag)
def _basic_return(self, frame_in): """Handle a Basic Return Frame and treat it as an error. :param specification.Basic.Return frame_in: Amqp frame. :return: """ reply_text = try_utf8_decode(frame_in.reply_text) message = ( "Message not delivered: %s (%s) to queue '%s' from exchange '%s'" % (reply_text, frame_in.reply_code, frame_in.routing_key, frame_in.exchange)) exception = AMQPMessageError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception)
def _close_connection(self, frame_in): """Connection Close. :param specification.Connection.Close frame_in: Amqp frame. :return: """ self._set_connection_state(Stateful.CLOSED) if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = ('Connection was closed by remote server: %s' % reply_text) exception = AMQPConnectionError(message, reply_code=frame_in.reply_code) self._connection.exceptions.append(exception)
def _close_connection(self, frame_in): """Connection Close. :param pamqp_spec.Connection.Close frame_in: Amqp frame. :return: """ self._set_connection_state(Stateful.CLOSED) if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = ( 'Connection was closed by remote server: %s' % reply_text ) exception = AMQPConnectionError(message, reply_code=frame_in.reply_code) self._connection.exceptions.append(exception)
def _close_channel(self, frame_in): """Close Channel. :param specification.Channel.Close frame_in: Amqp frame. :return: """ self.set_state(self.CLOSED) if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = ('Channel %d was closed by remote server: %s' % (self._channel_id, reply_text)) exception = AMQPChannelError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception) self.close()
def _basic_return(self, frame_in): """Handle Basic Return and treat it as an error. :param pamqp_spec.Return frame_in: Amqp frame. :return: """ reply_text = try_utf8_decode(frame_in.reply_text) message = ("Message not delivered: %s (%s) to queue '%s' " "from exchange '%s'" % (reply_text, frame_in.reply_code, frame_in.routing_key, frame_in.exchange)) exception = AMQPMessageError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception)
def body(self): """Return the Message Body. If auto_decode is enabled, the body will automatically be decoded using decode('utf-8') if possible. :rtype: bytes|str|unicode """ if not self._auto_decode: return self._body if 'body' in self._decode_cache: return self._decode_cache['body'] body = try_utf8_decode(self._body) self._decode_cache['body'] = body return body
def _try_decode_utf8_content(self, content, content_type): """Generic function to decode content. :param object content: :return: """ if not self._auto_decode or not content: return content if content_type in self._cache: return self._cache[content_type] if isinstance(content, dict): return self._try_decode_dict_content(content) content = try_utf8_decode(content) self._cache[content_type] = content return content
def body(self): """Return the Message Body. If auto_decode is enabled, the body will automatically be decoded using decode('utf-8') if possible. :rtype: bytes|str|unicode """ if not self._auto_decode: return self._body if 'body' in self._cache: return self._cache['body'] body = try_utf8_decode(self._body) self._cache['body'] = body return body
def _close_channel(self, frame_in): """Close Channel. :param specification.Channel.Close frame_in: Channel Close frame. :return: """ self.set_state(self.CLOSED) self.remove_consumer_tag() if self._inbound: del self._inbound[:] self.exceptions.append( AMQPChannelError( 'Channel %d was closed by remote server: %s' % (self._channel_id, try_utf8_decode(frame_in.reply_text)), reply_code=frame_in.reply_code))
def _close_channel(self, frame_in): """Close Channel. :param pamqp_spec.Channel.Close frame_in: Amqp frame. :return: """ self.remove_consumer_tag() if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = 'Channel %d was closed by remote server: %s' % \ (self._channel_id, reply_text) exception = AMQPChannelError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception) del self._inbound[:] self.set_state(self.CLOSED)
def _try_decode_utf8_content(self, content, content_type): """Generic function to decode content. :param object content: :return: """ if not self._auto_decode or not content: return content if content_type in self._decode_cache: return self._decode_cache[content_type] if isinstance(content, dict): content = self._try_decode_dict(content) else: content = try_utf8_decode(content) self._decode_cache[content_type] = content return content
def _send_start_ok(self, frame_in): """Send Start OK frame. :param specification.Connection.Start frame_in: Amqp frame. :return: """ if 'PLAIN' not in try_utf8_decode(frame_in.mechanisms): exception = AMQPConnectionError( 'Unsupported Security Mechanism(s): %s' % frame_in.mechanisms) self._connection.exceptions.append(exception) return credentials = self._plain_credentials() start_ok_frame = specification.Connection.StartOk( mechanism=AUTH_MECHANISM, client_properties=self._client_properties(), response=credentials, locale=LOCALE) self._write_frame(start_ok_frame)
def _send_start_ok(self, frame_in): """Send Start OK frame. :param pamqp_spec.Connection.Start frame_in: Amqp frame. :return: """ if 'PLAIN' not in try_utf8_decode(frame_in.mechanisms): exception = AMQPConnectionError( 'Unsupported Security Mechanism(s): %s' % frame_in.mechanisms ) self._connection.exceptions.append(exception) return credentials = self._plain_credentials() start_ok_frame = pamqp_spec.Connection.StartOk( mechanism=AUTH_MECHANISM, client_properties=self._client_properties(), response=credentials, locale=LOCALE) self._write_frame(start_ok_frame)
def _close_channel(self, frame_in): """Close Channel. :param specification.Channel.Close frame_in: Amqp frame. :return: """ self.set_state(self.CLOSED) if frame_in.reply_code != 200: reply_text = try_utf8_decode(frame_in.reply_text) message = ( 'Channel %d was closed by remote server: %s' % ( self._channel_id, reply_text ) ) exception = AMQPChannelError(message, reply_code=frame_in.reply_code) self.exceptions.append(exception) self.close()
def test_compatibility_fail_silently_on_utf_16(self): x = 'hello'.encode('utf-16') self.assertEqual(compatibility.try_utf8_decode(x), x)
def test_compatibility_py2_try_utf8_decode(self): x = unicode('hello world') self.assertEqual(str(x), compatibility.try_utf8_decode(x))
def test_py2_try_utf8_decode(self): x = unicode("hello world") self.assertEqual(str(x), compatibility.try_utf8_decode(x))
def test_py3_try_utf8_decode(self): x = bytes("hello world", "utf-8") self.assertEqual(x.decode("utf-8"), compatibility.try_utf8_decode(x))
def test_compatibility_py3_try_utf8_decode(self): x = bytes('hello world', 'utf-8') self.assertEqual(x.decode('utf-8'), compatibility.try_utf8_decode(x))
def test_try_utf8_decode_on_integer(self): x = 5 self.assertEqual(x, compatibility.try_utf8_decode(x))
def test_try_utf8_decode_on_dict(self): x = dict(hello="world") self.assertEqual(x, compatibility.try_utf8_decode(x))
def test_compatibility_try_utf8_decode_on_dict(self): x = dict(hello='world') self.assertEqual(x, compatibility.try_utf8_decode(x))
def test_compatibility_fail_silently_on_utf_32(self): x = 'abc'.encode('utf-32') self.assertEqual(compatibility.try_utf8_decode(x), x)
def test_compatibility_try_utf8_decode_on_integer(self): x = 5 self.assertEqual(x, compatibility.try_utf8_decode(x))