From c728ffc74121ba668965cc5e528129f82d631e19 Mon Sep 17 00:00:00 2001 From: Brian Cardarella Date: Sat, 3 Feb 2024 21:11:47 -0500 Subject: [PATCH] Support case insensitive headers (#161) Closes #160 --- lib/mail/parsers/rfc_2822.ex | 18 +++++++++--------- mix.lock | 13 +++++-------- test/mail/parsers/rfc_2822_test.exs | 9 +++++++++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/mail/parsers/rfc_2822.ex b/lib/mail/parsers/rfc_2822.ex index 166d479..a381596 100644 --- a/lib/mail/parsers/rfc_2822.ex +++ b/lib/mail/parsers/rfc_2822.ex @@ -258,7 +258,7 @@ defmodule Mail.Parsers.RFC2822 do [name, body] = String.split(header, ":", parts: 2) key = String.downcase(name) decoded = parse_encoded_word(body) - headers = put_header(message.headers, key, parse_header_value(name, decoded)) + headers = put_header(message.headers, key, String.downcase(name) |> parse_header_value(decoded)) message = %{message | headers: headers} parse_headers(message, tail) end @@ -284,36 +284,36 @@ defmodule Mail.Parsers.RFC2822 do defp parse_header_value(key, "\t" <> value), do: parse_header_value(key, value) - defp parse_header_value("To", value), + defp parse_header_value("to", value), do: parse_recipient_value(value) - defp parse_header_value("CC", value), + defp parse_header_value("cc", value), do: parse_recipient_value(value) - defp parse_header_value("From", value), + defp parse_header_value("from", value), do: parse_recipient_value(value) |> List.first() - defp parse_header_value("Reply-To", value), + defp parse_header_value("reply-to", value), do: parse_recipient_value(value) |> List.first() - defp parse_header_value("Date", timestamp), + defp parse_header_value("date", timestamp), do: to_datetime(timestamp) - defp parse_header_value("Received", value), + defp parse_header_value("received", value), do: parse_received_value(value) - defp parse_header_value("Content-Type", value) do + defp parse_header_value("content-type", value) do case parse_structured_header_value(value) do [_ | _] = header -> header <> -> [value, {"charset", "us-ascii"}] end end - defp parse_header_value("Content-Disposition", value), + defp parse_header_value("content-disposition", value), do: parse_structured_header_value(value) defp parse_header_value(_key, value), diff --git a/mix.lock b/mix.lock index 3f80712..ad250b7 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,8 @@ %{ - "earmark": {:hex, :earmark, "1.4.10", "bddce5e8ea37712a5bfb01541be8ba57d3b171d3fa4f80a0be9bcf1db417bcaf", [:mix], [{:earmark_parser, ">= 1.4.10", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "12dbfa80810478e521d3ffb941ad9fbfcbbd7debe94e1341b4c4a1b2411c1c27"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.33", "3c3fd9673bb5dcc9edc28dd90f50c87ce506d1f71b70e3de69aa8154bc695d44", [:mix], [], "hexpm", "2d526833729b59b9fdb85785078697c72ac5e5066350663e5be6a1182da61b8f"}, - "ex_doc": {:hex, :ex_doc, "0.30.3", "bfca4d340e3b95f2eb26e72e4890da83e2b3a5c5b0e52607333bf5017284b063", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "fbc8702046c1d25edf79de376297e608ac78cdc3a29f075484773ad1718918b6"}, - "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"}, - "mimerl": {:hex, :mimerl, "1.1.0"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, - "plug": {:hex, :plug, "1.1.0"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, } diff --git a/test/mail/parsers/rfc_2822_test.exs b/test/mail/parsers/rfc_2822_test.exs index 7da2ec6..dd1b9a4 100644 --- a/test/mail/parsers/rfc_2822_test.exs +++ b/test/mail/parsers/rfc_2822_test.exs @@ -687,6 +687,15 @@ defmodule Mail.Parsers.RFC2822Test do assert message.headers["content-type"] == ["text/html", {"charset", "us-ascii"}] end + test "content-type with atypical casing" do + message = + parse_email(""" + Content-type: text/html; charset=us-ascii + """) + + assert message.headers["content-type"] == ["text/html", {"charset", "us-ascii"}] + end + test "content-type with implicit charset" do message = parse_email("""