achilleasa / dart_amqp

Dart AMQP client implementing protocol version 0.9.1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues decoding strings with ØÆÅ

HelgeSverre opened this issue · comments

If i publish a message to a queue, where the message is a string containing Ø, Æ or Å, an error is thrown:

FormatException: Bad UTF-8 encoding 0xf8 (at offset 21)

Most likely caused by this line, not sure how to fix it thought, any thoughts on a workaround?

https://github.com/achilleasa/dart_amqp/blob/master/lib/src/protocol/frame/impl/decoded_message_impl.dart#L51

Code to replicate:

import 'dart:convert';

import 'package:dart_amqp/dart_amqp.dart';

void main() async {
  var client = await Client(
    settings: ConnectionSettings(
      host: "localhost",
      port: 5672,
      authProvider: PlainAuthenticator(
        "rabbitmq",
        "rabbitmq",
      ),
    ),
  );

  var queueName = "example_queue";

  // Setup a listener for a queue
  client
      .channel()
      .then((channel) => channel.queue(queueName))
      .then((Queue queue) => queue.consume())
      .then((Consumer consumer) {
    consumer.listen((AmqpMessage message) {
      // Both will fail with the following exception:
      // FormatException: Bad UTF-8 encoding 0xf8 (at offset 21)
      print(message.payloadAsString);
      print(message.payloadAsJson);
    });
  });

  // Publish a message to the queue
  client
      .channel()
      .then((channel) => channel.queue(queueName))
      .then((Queue queue) {
    // Publish the JSON string
    queue.publish("This string contains ø, æ or å");
  });
}

DartPad with example:
https://dartpad.dartlang.org/94b3febd063256dd8b0445a698fb0c22

I have found a workaround:

If you encode the payload as Base64 and then decode it back using message.payloadAsString, it will work.

Thanks for reporting this. This is clearly a bug in the way that published messages are encoded. Let me investigate this further...

@HelgeSverre can you please verify that the proposed fix in #32 addresses the issues you are currently having with UTF8 values?

Can confirm that the following now works:

import 'dart:convert';

import 'package:dart_amqp/dart_amqp.dart';

void main() async {
  var client = await Client(
    settings: ConnectionSettings(
      host: "localhost",
      port: 5672,
      authProvider: PlainAuthenticator(
        "rabbitmq",
        "rabbitmq",
      ),
    ),
  );

  var queueName = "example_queue";

  // Setup a listener for a queue
  client
      .channel()
      .then((channel) => channel.queue(queueName))
      .then((Queue queue) => queue.consume())
      .then((Consumer consumer) {
    consumer.listen((AmqpMessage message) {
      // Both will fail with the following exception:
      // FormatException: Bad UTF-8 encoding 0xf8 (at offset 21)
      print(message.payloadAsString);
      print(message.payloadAsJson);
    });
  });

  // Publish a message to the queue
  client
      .channel()
      .then((channel) => channel.queue(queueName))
      .then((Queue queue) {
    // Publish the JSON string
    queue.publish({"url": "This string contains ø, æ or å"});
  });
}

However, publishing a plain string like this does still produce the same error:

queue.publish("This string contains ø, æ or å");

@achilleasa

@HelgeSverre Can you double-check that you are not trying to process an un-acked message published using a previous version on the package? The linked PR includes tests for both strings and json payloads

@HelgeSverre Can you double-check that you are not trying to process an un-acked message published using a previous version on the package? The linked PR includes tests for both strings and json payloads

Ahh silly me, that is exactly what i was doing :P

Seems to work with both json and a plain string, excellent work. 👍