rschreijer / lutung

Lutung - A Java Mandrill API Connector
179 stars 119 forks source link

Parsing raw messages don't handle headers with multiple values #89

Open edslocombe opened 6 years ago

edslocombe commented 6 years ago

I've noticed that when asking Mandrill to parse a raw email the headers attribute in the response cannot always be deserialised. Values for a given header can be a string or an array.

Headers with multiple values cannot be deserialised into a MandrillMessage since header values are only expected to be strings.

As an example;

A response from the Mandrill parse request:

{
  ...
  "headers": {
    "Return-Path": "<me@googlemail.com>",
    "Received": [
      "from mail123.google.com (mail.google.com [123.123.123]) by inbound-smtp.eu-west-1.amazonaws.com with SMTP id 23456 for another@mail.co.uk; Fri, 15 Jun 2018 09:30:43 +0000 (UTC)",
      "by mail123.google.com with SMTP id 1234 for <another@mail.co.uk>; Fri, 15 Jun 2018 02:30:43 -0700 (PDT)"
    ],
  ...
}

The library then throws the following:

Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 70 path $.headers.
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
    at com.google.gson.Gson.fromJson(Gson.java:888)
    at com.google.gson.Gson.fromJson(Gson.java:853)
    at com.google.gson.Gson.fromJson(Gson.java:802)
    at com.google.gson.Gson.fromJson(Gson.java:774)
    at com.microtripit.mandrillapp.lutung.model.MandrillRequest.handleResponse(MandrillRequest.java:64)
    ... 8 more
Caused by: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 70 path $.headers.
    at com.google.gson.stream.JsonReader.nextString(JsonReader.java:825)
    at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:401)
    at com.google.gson.internal.bind.TypeAdapters$16.read(TypeAdapters.java:389)

I am potentially able to raise a PR that fixes this but will want a release with the fix fairly quickly. Will see how I get on.

edslocombe commented 6 years ago

I have now understood that the above example isn't enough to cause the issue; it's when we have duplicate email headers, which apparently is possible / valid for a number of headers.

An example unit test that'd run (but fail currently) in MandrillMessagesApiTest:

    @Test
    public void testParse03_mutlipleValuesForSingleHeader() throws IOException, MandrillApiError {
        String testUnparsedMsg =
            "Return-Path: <me@googlemail.com>\n" +
            "Received: from mail47.google.com\n" +
            "Received: by mail47.google.com with SMTP id 123\n" +
            "To: " + mailToAddress()+ "\n" +
            "Subject: Lutung test subject\n\n" +
            "Sup mandrill !";
        MandrillMessage parsedMessage = mandrillApi.messages().parse(testUnparsedMsg);
        Assume.assumeNotNull(parsedMessage);
        Assert.assertEquals("Lutung test subject", parsedMessage.getSubject());
    }