CC: | jonathan.stowe [...] db.com |
Subject: | Encoding issue for generated frames |
Hi,
We are using Net::AMQP via POE::Component::Client::AMQP in an application where exchanges and queue and the bindings thereof are declared based on configuration stored in a database.
If the database is Oracle and the "NLS_LANG" is set to 'ENGLISH_UNITED KINGDOM.AL32UTF8' then we get an
=INFO REPORT==== 30-Oct-2013::13:37:58 ===
accepting AMQP connection <0.395.0> (127.0.0.1:43461 -> 127.0.0.1:5672)
=ERROR REPORT==== 30-Oct-2013::13:37:58 ===
AMQP connection <0.395.0> (running), channel 1 - error:
{amqp_error,frame_error,
"type 1, first 16 octets = <<0,40,0,10,0,0,20,97,99,116,105,111,110,95,113,117>>: {invalid_frame_end_marker,\n 195}",
none}
=ERROR REPORT==== 30-Oct-2013::13:38:01 ===
closing AMQP connection <0.395.0> (127.0.0.1:43461 -> 127.0.0.1:5672):
From the RabbitMQ on declaring an Exchange, Queue or attempting a binding.
We have remedied this by encoding the queue and exchange names and the exchange type to utf-8 explcitly before creating the declaration frames which are passed to send_frames.
e.g.
sub protocol_declare_frame
{
my ( $self ) = @_;
my $class = $self->protocol()->exchange_declare_class();
my $type = $self->exchange_type() || 'fanout';
if ( Encode::is_utf8($type) )
{
$type = Encode::encode_utf8($type);
}
my $exchange = $self->name();
if ( Encode::is_utf8($exchange) )
{
$exchange = Encode::encode_utf8($exchange);
}
$self->log_debug("Protocol from for '$exchange' : type '$type'");
my @args = (exchange => $exchange,
type => $type,
durable => $self->durable(),
auto_delete => $self->auto_delete(), );
my $frame = $class->new(@args);
return $frame;
}
(where $self->protocol()->exchange_declare_class() is Net::AMQ::Frame::Method::ExchangeDeclare or whatever)
... (and then the returned from gets to send_frames()).
I guess however that this could best be applied universally in the helpers in Net::AMQP::Common
Thanks for making the otherwise fantastically usefully modules.