Skip to content

Commit 7726064

Browse files
Add charset handler to body where charset is present
1 parent 66f6fe7 commit 7726064

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

lib/mail/parsers/rfc_2822.ex

+13-4
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,11 @@ defmodule Mail.Parsers.RFC2822 do
524524
message
525525
end
526526

527-
defp parse_body(%Mail.Message{} = message, lines, _opts) do
527+
defp parse_body(%Mail.Message{} = message, lines, opts) do
528528
decoded =
529529
lines
530530
|> join_body()
531-
|> decode(message)
531+
|> decode(message, opts)
532532

533533
Map.put(message, :body, decoded)
534534
end
@@ -580,9 +580,18 @@ defmodule Mail.Parsers.RFC2822 do
580580
end
581581
end
582582

583-
defp decode(body, message) do
583+
defp decode(body, message, opts) do
584584
body = String.trim_trailing(body)
585+
content_type = message.headers["content-type"]
586+
charset = Mail.Proplist.get(content_type, "charset")
585587
transfer_encoding = Mail.Message.get_header(message, "content-transfer-encoding")
586-
Mail.Encoder.decode(body, transfer_encoding)
588+
decoded = Mail.Encoder.decode(body, transfer_encoding)
589+
590+
if charset do
591+
charset_handler = Keyword.get(opts, :charset_handler, fn _, string -> string end)
592+
charset_handler.(charset, decoded)
593+
else
594+
decoded
595+
end
587596
end
588597
end

lib/mail/proplist.ex

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ defmodule Mail.Proplist do
8686
* `list` - the list to look in
8787
* `key` - the key of the pair to retrieve it's value
8888
"""
89+
def get(nil, _key), do: nil
90+
8991
def get(list, key) do
9092
case :proplists.get_value(key, list) do
9193
:undefined -> nil

test/mail/parsers/rfc_2822_test.exs

+10-4
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,9 @@ defmodule Mail.Parsers.RFC2822Test do
785785
786786
------=_Part_295474_20544590.1456382229928
787787
Content-Type: text/plain; charset="Windows-1252"
788-
Content-Transfer-Encoding: quoted-printable
788+
Content-Transfer-Encoding: quoted-printable
789789
790-
fran=E7aise pr=E8s =E0 th=E9=E2tre lumi=E8re
790+
fran=E7aise pr=E8s =E0 th=E9=E2tre lumi=E8re
791791
792792
------=_Part_295474_20544590.1456382229928
793793
Content-Type: application/octet-stream;
@@ -833,6 +833,7 @@ defmodule Mail.Parsers.RFC2822Test do
833833
assert [part1, part2, part3, part4] = message.parts
834834

835835
assert %{headers: %{"content-type" => ["text/plain" | _]}} = part1
836+
assert part1.body == "fran\xE7aise pr\xE8s \xE0 th\xE9\xE2tre lumi\xE8re"
836837

837838
assert %{
838839
headers: %{
@@ -860,9 +861,13 @@ defmodule Mail.Parsers.RFC2822Test do
860861
|> String.graphemes()
861862
|> Enum.map(fn
862863
# Windows-1252
863-
<<233>> -> "é"
864+
<<0xE0>> -> "à"
865+
<<0xE2>> -> "â"
866+
<<0xE7>> -> "ç"
867+
<<0xE8>> -> "è"
868+
<<0xE9>> -> "é"
864869
# Windows-1258
865-
<<236>> -> "\u0301"
870+
<<0xEC>> -> "\u0301"
866871
char -> char
867872
end)
868873
|> Enum.join()
@@ -871,6 +876,7 @@ defmodule Mail.Parsers.RFC2822Test do
871876

872877
assert [part1, part2, part3, part4] = message.parts
873878
assert %{headers: %{"content-type" => ["text/plain" | _]}} = part1
879+
assert part1.body == "française près à théâtre lumière"
874880

875881
assert %{
876882
headers: %{

0 commit comments

Comments
 (0)