Test files › Email › html-multipart.eml
Sample EML file (html multipart)
multipart/alternative carrying both a text/plain and a text/html version of the same message.
↓ Download html-multipart.eml| Filename | html-multipart.eml |
| Format | EML |
| Size | 593 bytes (593 bytes) |
| MIME type | message/rfc822 |
| SHA-256 | f0092b2f4414211ce1f3d5813729cc7ed0646f9f0fd4df5fd1de1e5ffd193a07 |
What this file catchesClients that pick the wrong alternative, or render the HTML part as literal text. Also catches parsers that stop at the first part.
Handle it in code
Each snippet below was run against this exact file with Python 3.14.4 and Node 24.15.0 when this page was built, and the output shown is what it printed.
Python
Parse with the modern email API (policy=default): it decodes encoded headers and bodies, and get_body picks the readable part. Treat attachment names as hostile: keep only the base name, replace unusual characters, and refuse names that run as programs. Compare the display name with the real address too, the oldest spoofing trick there is.
import email
import re
from email import policy
from email.utils import parseaddr
RUNS = (".exe", ".scr", ".bat", ".cmd", ".com", ".js", ".vbs", ".ps1", ".msi", ".jar", ".lnk")
with open("html-multipart.eml", "rb") as f:
msg = email.message_from_binary_file(f, policy=policy.default)
name, addr = parseaddr(str(msg["From"] or ""))
print("from:", addr or "(missing)", "| subject:", msg["Subject"] or "(missing)")
for header in ("Date", "Message-ID"):
if msg[header] is None:
print(f"warning: no {header} header")
if "@" in name and parseaddr(name)[1].lower() != addr.lower():
print(f"warning: display name {name!r} is not the real sender")
body = msg.get_body(preferencelist=("plain", "html"))
text = body.get_content().strip() if body else ""
print(f"body: {body.get_content_type() if body else '(none)'} {text[:50]!r}")
for part in msg.iter_attachments():
kind = part.get_content_type()
if kind == "message/rfc822":
print("attached message:", part.get_content()["Subject"])
continue
raw = part.get_filename() or ""
base = raw.replace("\\", "/").rsplit("/", 1)[-1]
safe = re.sub(r"[^\w.\- ]", "_", base).strip(". ") or "attachment"
verdict = "blocked, it runs as a program" if safe.lower().endswith(RUNS) else "save as " + repr(safe)
print(f"attachment: {kind} {raw!r}: {verdict}")
if kind == "application/ms-tnef":
print(" Outlook's TNEF wrapper: the real attachments are inside it")Run against this file, it prints: from: ava.stone@example.test | subject: Quarterly report
body: text/plain 'Plain text version.'
Related guides and tools
Sample EML and MSG email filesReserved domains for test emailCharacter encodingsCheck a file's real typeVerify its SHA-256
Download & verify
curl -fsSL -o "html-multipart.eml" "https://files.hexaqa.com/email/html-multipart.eml"
curl -fsSL "https://files.hexaqa.com/email/html-multipart.eml" | sha256sum
# expect: f0092b2f4414211ce1f3d5813729cc7ed0646f9f0fd4df5fd1de1e5ffd193a07