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
unpackmade.
Enums§
- Mhtml
Error - 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, soiso-8859-1reads 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
referenceagainstbase(RFC 3986, 5.2, simplified to the shapes archives use).Nonewhen the base has no scheme. - safe_
join dir/name, refused unlessnameis a single plain file name.- unpack
- Unpacks the archive in
dataintodir, which must exist and should be empty: the root page asindex.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
pathintodir, refusing a file larger than twice the size limit (base64 makes parts a third larger).