Skip to main content

Module mhtml

Module mhtml 

Source
Expand description

MHTML web archives (.mhtml): reading the MIME parts (RFC 2045, 2046, 2047 and 2557) and unpacking them into a folder a browser engine can load from disk.

WebKit on macOS doesn’t open MHTML, so the web viewer and the import thumbnail use unpack: every part becomes a file in a fresh folder (the root page as index.html), and the references in the HTML and CSS parts that point at other parts, by Content-Location or cid:, are rewritten to the files’ relative names. Whatever isn’t in the archive is left as written, and a Content Security Policy put at the top of every page lets it load only file:, data: and blob: resources, so nothing is fetched from the network.

The reader tolerates CRLF or LF line ends, a missing closing boundary, folded headers, nested multiparts, quoted-printable with =0D line ends, encoded words in headers, and the shapes Chrome, Edge and Word write (“Save as MHTML”: full URLs as Content-Location, cid: references, Snapshot-Content-Location). Text parts are decoded from their charset with encoding_rs and written as UTF-8 with a byte order mark, which takes precedence over any charset the page declares.

QuickLook’s HTML renderer loads a page’s files through a scheme of its own, which no policy source matches, so the import thumbnail unpacks without the policy (Policy::None); QuickLook fetches nothing from the network itself.

Unpacking is bounded by Limits (total decoded size and part count), and file names are made by falcon, never taken as paths from the archive, so nothing is written outside the target folder.

Structs§

Archive
A parsed archive.
Limits
Bounds on what an archive may unpack to.
Part
One part of an archive, decoded from its transfer encoding.
Unpacked
What unpack made.

Enums§

MhtmlError
Why an archive couldn’t be read or unpacked.
Policy
Whether unpacked pages carry CSP.

Constants§

CSP
The policy put at the top of every unpacked page: the archive’s own files and inline data load, the network doesn’t.
MAX_PARTS
How many parts an archive may have, by default.
MAX_TOTAL
How much an archive may unpack to, by default: 256 MB of decoded parts.
ROOT_NAME
The root page’s file name in the unpacked folder.

Functions§

decode_text
A text part’s characters: by its byte order mark, else its charset, else the charset it declares itself, else UTF-8 when it is valid UTF-8, else windows-1252 (as browsers read undeclared Latin text). Labels are WHATWG’s, so iso-8859-1 reads as windows-1252, as in browsers.
decode_words
Decodes RFC 2047 encoded words (=?utf-8?Q?Caf=C3=A9?=, =?iso-8859-1?B?...?=) in a header value; blanks between two encoded words are dropped, unknown charsets and malformed words are kept as written.
parse
Reads an archive. A file whose top header isn’t a multipart but is a single HTML entity (some writers do this) is an archive of one page.
percent_decode
Percent-decodes s (invalid escapes kept), reading the bytes as UTF-8.
percent_encode
Percent-encodes a file name for use in a relative URL: everything but ASCII letters, digits and -._~.
resolve
Resolves reference against base (RFC 3986, 5.2, simplified to the shapes archives use). None when the base has no scheme.
safe_join
dir/name, refused unless name is a single plain file name.
unpack
Unpacks the archive in data into dir, which must exist and should be empty: the root page as index.html, every other part under a name falcon makes, HTML and CSS rewritten to point at each other’s files.
unpack_file
Unpacks the archive file at path into dir, refusing a file larger than twice the size limit (base64 makes parts a third larger).