IMAP server passing all tests.

This commit is contained in:
mdecimus 2023-07-03 16:38:49 +02:00
parent 048a65a019
commit 0a8fdd9008
46 changed files with 598 additions and 298 deletions

197
Cargo.lock generated
View file

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
@ -188,7 +197,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -210,18 +219,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
name = "async-trait"
version = "0.1.68"
version = "0.1.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -294,7 +303,7 @@ dependencies = [
"futures-util",
"http",
"http-body 0.4.5",
"hyper 0.14.26",
"hyper 0.14.27",
"itoa",
"matchit",
"memchr",
@ -326,6 +335,21 @@ dependencies = [
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "base16ct"
version = "0.2.0"
@ -417,7 +441,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.22",
"syn 2.0.23",
"which",
]
@ -429,9 +453,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.2"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
[[package]]
name = "bitpacking"
@ -620,9 +644,9 @@ dependencies = [
[[package]]
name = "const-oid"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc"
[[package]]
name = "constant_time_eq"
@ -839,9 +863,9 @@ dependencies = [
[[package]]
name = "der"
version = "0.7.6"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17"
checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946"
dependencies = [
"const-oid",
"pem-rfc7468 0.7.0",
@ -941,7 +965,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -962,7 +986,7 @@ version = "0.16.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428"
dependencies = [
"der 0.7.6",
"der 0.7.7",
"digest 0.10.7",
"elliptic-curve",
"rfc6979",
@ -1233,7 +1257,7 @@ checksum = "83c8d52fe8b46ab822b4decdcc0d6d85aeedfc98f0d52ba2bd4aec4a97807516"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
"try_map",
]
@ -1313,7 +1337,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -1397,6 +1421,12 @@ dependencies = [
"polyval",
]
[[package]]
name = "gimli"
version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]]
name = "glob"
version = "0.3.1"
@ -1470,15 +1500,6 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
@ -1598,9 +1619,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "hyper"
version = "0.14.26"
version = "0.14.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
dependencies = [
"bytes",
"futures-channel",
@ -1649,7 +1670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
dependencies = [
"http",
"hyper 0.14.26",
"hyper 0.14.27",
"rustls 0.21.2",
"tokio",
"tokio-rustls 0.24.1",
@ -1661,7 +1682,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper 0.14.26",
"hyper 0.14.27",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
@ -1779,7 +1800,7 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"hermit-abi",
"libc",
"windows-sys 0.48.0",
]
@ -1798,9 +1819,9 @@ dependencies = [
[[package]]
name = "ipnet"
version = "2.7.2"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]]
name = "itertools"
@ -1813,9 +1834,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "c0aa48fab2893d8a49caa94082ae8488f4e1050d73b367881dcd2198f4199fd8"
[[package]]
name = "jemalloc-sys"
@ -2136,7 +2157,7 @@ dependencies = [
[[package]]
name = "mail-parser"
version = "0.8.2"
source = "git+https://github.com/stalwartlabs/mail-parser#154591697f7ac92326fa7c532e1827e87ae8d30d"
source = "git+https://github.com/stalwartlabs/mail-parser#da62659eb609a8222edf7d1f57b28550a853921e"
dependencies = [
"encoding_rs",
"serde",
@ -2390,9 +2411,9 @@ dependencies = [
[[package]]
name = "num-bigint-dig"
version = "0.8.2"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
@ -2438,14 +2459,23 @@ dependencies = [
[[package]]
name = "num_cpus"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi 0.2.6",
"hermit-abi",
"libc",
]
[[package]]
name = "object"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
dependencies = [
"memchr",
]
[[package]]
name = "oid-registry"
version = "0.6.1"
@ -2490,7 +2520,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -2798,7 +2828,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -2812,29 +2842,29 @@ dependencies = [
[[package]]
name = "pin-project"
version = "1.1.0"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.0"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
[[package]]
name = "pin-utils"
@ -2870,7 +2900,7 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der 0.7.6",
"der 0.7.7",
"spki 0.7.2",
]
@ -2915,7 +2945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
dependencies = [
"proc-macro2",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -3042,9 +3072,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.28"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
dependencies = [
"proc-macro2",
]
@ -3187,7 +3217,7 @@ dependencies = [
"h2",
"http",
"http-body 0.4.5",
"hyper 0.14.26",
"hyper 0.14.27",
"hyper-rustls",
"ipnet",
"js-sys",
@ -3302,7 +3332,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
dependencies = [
"bitflags 2.3.2",
"bitflags 2.3.3",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
@ -3362,6 +3392,12 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustc-hash"
version = "1.1.0"
@ -3379,9 +3415,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.37.20"
version = "0.37.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
dependencies = [
"bitflags 1.3.2",
"errno",
@ -3429,9 +3465,9 @@ dependencies = [
[[package]]
name = "rustls-pemfile"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
dependencies = [
"base64 0.21.2",
]
@ -3520,7 +3556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e"
dependencies = [
"base16ct",
"der 0.7.6",
"der 0.7.7",
"generic-array",
"pkcs8 0.10.2",
"subtle",
@ -3576,7 +3612,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -3624,7 +3660,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -3841,7 +3877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
dependencies = [
"base64ct",
"der 0.7.6",
"der 0.7.7",
]
[[package]]
@ -4123,9 +4159,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.22"
version = "2.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
dependencies = [
"proc-macro2",
"quote",
@ -4228,7 +4264,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -4306,11 +4342,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.28.2"
version = "1.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
"mio",
@ -4341,7 +4378,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -4421,7 +4458,7 @@ dependencies = [
"h2",
"http",
"http-body 0.4.5",
"hyper 0.14.26",
"hyper 0.14.27",
"hyper-timeout",
"percent-encoding",
"pin-project",
@ -4514,7 +4551,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
]
[[package]]
@ -4770,9 +4807,9 @@ dependencies = [
[[package]]
name = "uuid"
version = "1.3.4"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81"
checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be"
[[package]]
name = "valuable"
@ -4834,7 +4871,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
"wasm-bindgen-shared",
]
@ -4868,7 +4905,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.22",
"syn 2.0.23",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -5020,9 +5057,9 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.48.0"
version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
@ -5155,9 +5192,9 @@ dependencies = [
[[package]]
name = "xml-rs"
version = "0.8.14"
version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c"
checksum = "5a56c84a8ccd4258aed21c92f70c0f6dea75356b6892ae27c24139da456f9336"
[[package]]
name = "xxhash-rust"

View file

@ -284,18 +284,19 @@ impl SessionData {
.take()
.map(|state| state.deletions)
.unwrap_or_default();
let mut uid_to_id = std::mem::take(&mut current_state.uid_to_id);
for imap_id in current_state.id_to_imap.values_mut() {
if imap_id.uid != u32::MAX && !new_state.uid_to_id.contains_key(&imap_id.uid) {
let mut id_to_imap = AHashMap::with_capacity(current_state.id_to_imap.len());
for (id, imap_id) in std::mem::take(&mut current_state.id_to_imap) {
if !new_state.uid_to_id.contains_key(&imap_id.uid) {
// Add to deletions
deletions.push(*imap_id);
deletions.push(imap_id);
// Invalidate entries
uid_to_id.insert(imap_id.uid, u32::MAX);
imap_id.uid = u32::MAX;
current_state.uid_to_id.remove(&imap_id.uid);
} else {
id_to_imap.insert(id, imap_id);
}
}
current_state.uid_to_id = uid_to_id;
current_state.id_to_imap = id_to_imap;
// Update state
current_state.modseq = new_state.modseq;
@ -312,7 +313,6 @@ impl SessionData {
&self,
mailbox: &SelectedMailbox,
is_qresync: bool,
is_uid: bool,
) -> crate::op::Result<Option<u64>> {
// Resync mailbox
let modseq = self.synchronize_messages(mailbox).await?;
@ -324,13 +324,7 @@ impl SessionData {
let mut ids = next_state
.deletions
.into_iter()
.map(|id| {
if is_uid || is_qresync {
id.uid
} else {
id.seqnum
}
})
.map(|id| if is_qresync { id.uid } else { id.seqnum })
.collect::<Vec<u32>>();
ids.sort_unstable();
expunge::Response { is_qresync, ids }.serialize_to(&mut buf);
@ -393,15 +387,13 @@ impl SelectedMailbox {
if is_uid {
for (id, imap_id) in &state.id_to_imap {
if imap_id.uid != u32::MAX && sequence.contains(imap_id.uid, state.uid_max) {
if sequence.contains(imap_id.uid, state.uid_max) {
ids.insert(*id, *imap_id);
}
}
} else {
for (id, imap_id) in &state.id_to_imap {
if imap_id.uid != u32::MAX
&& sequence.contains(imap_id.seqnum, state.total_messages as u32)
{
if sequence.contains(imap_id.seqnum, state.total_messages as u32) {
ids.insert(*id, *imap_id);
}
}
@ -418,9 +410,7 @@ impl SelectedMailbox {
for imap_id in saved_ids.iter() {
if let Some(id) = state.uid_to_id.get(&imap_id.uid) {
if *id != u32::MAX {
ids.insert(*id, *imap_id);
}
ids.insert(*id, *imap_id);
}
}
@ -434,7 +424,7 @@ impl SelectedMailbox {
let state = self.state.lock();
if is_uid {
for uid in sequence.expand(state.uid_max) {
if state.uid_to_id.get(&uid).map_or(true, |id| *id == u32::MAX) {
if !state.uid_to_id.contains_key(&uid) {
deleted_ids.push(uid);
}
}
@ -448,11 +438,7 @@ impl SelectedMailbox {
} else if let Some(saved_ids) = self.get_saved_search().await {
let state = self.state.lock();
for id in saved_ids.iter() {
if state
.uid_to_id
.get(&id.uid)
.map_or(true, |id| *id == u32::MAX)
{
if !state.uid_to_id.contains_key(&id.uid) {
deleted_ids.push(if is_uid { id.uid } else { id.seqnum });
}
}

View file

@ -182,7 +182,7 @@ impl SessionData {
if !created_ids.is_empty() {
let (uids, uid_validity) = match selected_mailbox {
Some(selected_mailbox) if selected_mailbox.id == mailbox => {
self.write_mailbox_changes(&selected_mailbox, is_qresync, is_qresync)
self.write_mailbox_changes(&selected_mailbox, is_qresync)
.await
.map_err(|r| r.with_tag(&arguments.tag))?;
let mailbox = selected_mailbox.state.lock();

View file

@ -428,7 +428,7 @@ impl SessionData {
// Resynchronize source mailbox on a successful move
if did_move {
self.write_mailbox_changes(&src_mailbox, is_qresync, is_uid)
self.write_mailbox_changes(&src_mailbox, is_qresync)
.await
.map_err(|r| r.with_tag(&arguments.tag))?;
}

View file

@ -78,9 +78,9 @@ impl<T: AsyncRead> Session<T> {
}
// Parse sequence to operate on
let sequence = if let Some(Token::Argument(value)) = request.tokens.into_iter().next() {
match parse_sequence_set(&value) {
Ok(sequence) => match mailbox.sequence_to_ids(&sequence, is_uid).await {
let sequence = match request.tokens.into_iter().next() {
Some(Token::Argument(value)) if is_uid => match parse_sequence_set(&value) {
Ok(sequence) => match mailbox.sequence_to_ids(&sequence, true).await {
Ok(sequence) => Some(sequence),
Err(response) => {
return self
@ -93,9 +93,8 @@ impl<T: AsyncRead> Session<T> {
.write_bytes(StatusResponse::bad(err).with_tag(request.tag).into_bytes())
.await;
}
}
} else {
None
},
_ => None,
};
if let Err(response) = data.expunge(mailbox.clone(), sequence).await {
@ -108,10 +107,7 @@ impl<T: AsyncRead> Session<T> {
*mailbox.saved_search.lock() = SavedSearch::None;
// Synchronize messages
match data
.write_mailbox_changes(&mailbox, self.is_qresync, is_uid)
.await
{
match data.write_mailbox_changes(&mailbox, self.is_qresync).await {
Ok(_) => {
self.write_bytes(
StatusResponse::completed(Command::Expunge(is_uid))

View file

@ -815,24 +815,32 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
}
let mut message = self;
let sections_single = sections.len() == 1;
let mut sections_iter = sections.iter().peekable();
let mut sections_iter = sections.iter().enumerate().peekable();
while let Some(section) = sections_iter.next() {
while let Some((section_num, section)) = sections_iter.next() {
match section {
Section::Part { num } => {
part = if let Some(sub_part_ids) = part.sub_parts() {
sub_part_ids
.get((*num).saturating_sub(1) as usize)
.and_then(|pos| message.parts.get(*pos))
} else if *num == 1 && (sections_single || part.is_message()) {
} else if *num == 1 && (section_num == sections.len() - 1 || part.is_message())
{
Some(part)
} else {
None
}?;
if let (PartType::Message(nested_message), Some(_)) =
(&part.body, sections_iter.peek())
if let (
PartType::Message(nested_message),
Some((
_,
Section::Part { .. }
| Section::Header
| Section::HeaderFields { .. }
| Section::Text,
)),
) = (&part.body, sections_iter.peek())
{
message = nested_message;
part = message.root_part();
@ -888,7 +896,9 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
let mut headers =
Vec::with_capacity(part.offset_body.saturating_sub(part.offset_header));
for header in &part.headers {
if header.name.is_mime_header() {
if header.name.is_mime_header()
|| header.name.as_str().starts_with("Content-")
{
headers.extend_from_slice(header.name.as_str().as_bytes());
headers.extend_from_slice(b":");
headers.extend_from_slice(
@ -937,18 +947,24 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
) -> Result<Option<BodyContents>, ()> {
let mut message = self;
let mut part = self.root_part();
let mut sections_iter = sections.iter().peekable();
let mut sections_iter = sections.iter().enumerate().peekable();
while let Some(section) = sections_iter.next() {
part = if let Some(part) = part
.sub_parts()
.and_then(|p| p.get((*section).saturating_sub(1) as usize))
.and_then(|p| message.parts.get(*p))
{
while let Some((section_num, num)) = sections_iter.next() {
part = if let Some(sub_part_ids) = part.sub_parts() {
if let Some(part) = sub_part_ids
.get((*num).saturating_sub(1) as usize)
.and_then(|pos| message.parts.get(*pos))
{
part
} else {
return Ok(None);
}
} else if *num == 1 && (section_num == sections.len() - 1 || part.is_message()) {
part
} else {
return Ok(None);
};
if let (PartType::Message(nested_message), Some(_)) = (&part.body, sections_iter.peek())
{
message = nested_message;
@ -973,13 +989,23 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
message.root_part().raw_header_offset()
..message.root_part().raw_end_offset(),
)
.unwrap_or(&b""[..]),
.unwrap_or_default(),
partial,
)
.into(),
)
.into(),
PartType::Multipart(_) => BodyContents::Bytes(
get_partial_bytes(
message
.raw_message
.get(part.raw_header_offset()..part.raw_end_offset())
.unwrap_or_default(),
partial,
)
.into(),
)
.into(),
PartType::Multipart(_) => None,
})
} else {
Err(())
@ -989,14 +1015,19 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
fn binary_size(&self, sections: &[u32]) -> Option<usize> {
let mut message = self;
let mut part = self.root_part();
let mut sections_iter = sections.iter().peekable();
let mut sections_iter = sections.iter().enumerate().peekable();
while let Some((section_num, num)) = sections_iter.next() {
part = if let Some(sub_part_ids) = part.sub_parts() {
sub_part_ids
.get((*num).saturating_sub(1) as usize)
.and_then(|pos| message.parts.get(*pos))
} else if *num == 1 && (section_num == sections.len() - 1 || part.is_message()) {
Some(part)
} else {
None
}?;
while let Some(section) = sections_iter.next() {
part = message.parts.get(
*part
.sub_parts()?
.get((*section).saturating_sub(1) as usize)?,
)?;
if let (PartType::Message(nested_message), Some(_)) = (&part.body, sections_iter.peek())
{
message = nested_message;
@ -1008,7 +1039,7 @@ impl<'x> AsImapDataItem<'x> for Message<'x> {
PartType::Text(text) | PartType::Html(text) => text.len(),
PartType::Binary(bytes) | PartType::InlineBinary(bytes) => bytes.len(),
PartType::Message(message) => message.root_part().raw_len(),
PartType::Multipart(_) => 0,
PartType::Multipart(_) => part.raw_len(),
}
.into()
}

View file

@ -213,10 +213,7 @@ impl SessionData {
if let Some(mailbox) = mailbox {
// Obtain changes since last sync
let modseq = mailbox.state.lock().modseq;
match self
.write_mailbox_changes(mailbox, is_qresync, is_qresync)
.await
{
match self.write_mailbox_changes(mailbox, is_qresync).await {
Ok(new_state) => {
if new_state == modseq {
return;

View file

@ -286,9 +286,7 @@ impl SessionData {
let state = mailbox.state.lock();
for imap_id in prev_saved_search.iter() {
if let Some(id) = state.uid_to_id.get(&imap_id.uid) {
if *id != u32::MAX {
set.insert(*id);
}
set.insert(*id);
}
}
} else {
@ -425,7 +423,7 @@ impl SessionData {
}
search::Filter::On(date) => {
filters.push(query::Filter::And);
filters.push(query::Filter::gt(Property::ReceivedAt, date as u64));
filters.push(query::Filter::ge(Property::ReceivedAt, date as u64));
filters.push(query::Filter::lt(
Property::ReceivedAt,
(date + 86400) as u64,
@ -443,15 +441,15 @@ impl SessionData {
}
search::Filter::SentOn(date) => {
filters.push(query::Filter::And);
filters.push(query::Filter::gt(Property::SentAt, date as u64));
filters.push(query::Filter::ge(Property::SentAt, date as u64));
filters.push(query::Filter::lt(Property::SentAt, (date + 86400) as u64));
filters.push(query::Filter::End);
}
search::Filter::SentSince(date) => {
filters.push(query::Filter::gt(Property::SentAt, date as u64));
filters.push(query::Filter::ge(Property::SentAt, date as u64));
}
search::Filter::Since(date) => {
filters.push(query::Filter::gt(Property::ReceivedAt, date as u64));
filters.push(query::Filter::ge(Property::ReceivedAt, date as u64));
}
search::Filter::Smaller(size) => {
filters.push(query::Filter::lt(Property::Size, size));
@ -722,12 +720,8 @@ impl SelectedMailbox {
impl MailboxState {
pub fn map_result_id(&self, document_id: u32, is_uid: bool) -> Option<(u32, ImapId)> {
if let Some(imap_id) = self.id_to_imap.get(&document_id) {
if imap_id.uid != u32::MAX {
return Some((if is_uid { imap_id.uid } else { imap_id.seqnum }, *imap_id));
}
}
if is_uid {
Some((if is_uid { imap_id.uid } else { imap_id.seqnum }, *imap_id))
} else if is_uid {
self.next_state.as_ref().and_then(|s| {
s.next_state
.id_to_imap

View file

@ -126,10 +126,13 @@ impl SessionData {
}
}
let mut threads = threads
.into_iter()
.map(|(_, messages)| messages)
.collect::<Vec<_>>();
threads.sort_unstable();
// Build response
Ok(Response {
is_uid,
threads: threads.into_iter().map(|(_, messages)| messages).collect(),
})
Ok(Response { is_uid, threads })
}
}

View file

@ -348,9 +348,6 @@ impl JMAP {
if let Some(value) = value.as_string() {
subject = thread_name(value).trim_text(MAX_SORT_FIELD_LENGTH);
}
if subject.is_empty() {
subject = "!";
}
}
_ => (),
}

View file

@ -299,6 +299,11 @@ impl IndexMessage for BatchBuilder {
}
}
// Add subject to index if missing
if !seen_headers[RfcHeader::Subject as usize] {
self.value(Property::Subject, "!", F_INDEX);
}
match part.body {
PartType::Text(text) => {
if part_id == preview_part_id {
@ -416,6 +421,7 @@ impl IntoOperations for EmailIndexBuilder {
};
// Remove properties from index
let mut has_subject = false;
for (property, value) in self.inner.properties {
match (&property, value) {
(Property::Size, Value::UnsignedInt(size)) => {
@ -476,6 +482,7 @@ impl IntoOperations for EmailIndexBuilder {
},
F_INDEX | options,
);
has_subject = true;
}
(Property::HasAttachment, Value::Bool(true)) => {
batch.bitmap(Property::HasAttachment, (), options);
@ -483,6 +490,10 @@ impl IntoOperations for EmailIndexBuilder {
_ => {}
}
}
if !has_subject {
batch.value(Property::Subject, "!", F_INDEX | options);
}
}
}

View file

@ -123,9 +123,6 @@ impl JMAP {
_ => "",
})
.trim_text(MAX_SORT_FIELD_LENGTH);
if subject.is_empty() {
subject = "!";
}
}
_ => (),
}
@ -295,7 +292,14 @@ impl JMAP {
loop {
// Find messages with matching references
let mut filters = Vec::with_capacity(references.len() + 3);
filters.push(Filter::eq(Property::Subject, thread_name));
filters.push(Filter::eq(
Property::Subject,
if !thread_name.is_empty() {
thread_name
} else {
"!"
},
));
filters.push(Filter::Or);
for reference in references {
filters.push(Filter::eq(Property::MessageId, *reference));

View file

@ -264,7 +264,7 @@ impl Store {
item.file_name().to_str().and_then(parse_timestamp)
{
if now.saturating_sub(timestamp) > ttl {
fs::remove_file(item.path()).await?;
let _ = fs::remove_file(item.path()).await;
} else {
total_bytes += metadata.len() as usize;
total_files += 1;

View file

@ -30,9 +30,9 @@ state: created
#* 3 recent
2 ok fetch 1:3 (flags internaldate)
* 3 fetch (flags (\seen) internaldate $date1)
* 2 fetch (flags (\answered \flagged) internaldate $date2)
* 1 fetch (flags () internaldate $date4)
? 1 fetch (flags (\seen) internaldate $date1)
? 2 fetch (flags (\answered \flagged) internaldate $date2)
? 3 fetch (flags () internaldate $date4)
# keywords aren't required to be created on COPY, so help the server here
2 ok store 3 +flags ($$keyword1 $$keyword2)

View file

@ -22,7 +22,7 @@ Subject: m1
m1 body
--foo
X-Mime: m2 header
Content-Custom: m2 header
From: m2@example.com
Subject: m2
@ -31,7 +31,6 @@ m2 body
--foo--
epilogue
}}})
@ -52,7 +51,7 @@ Subject: m1
m1 body
--foo
X-Mime: m2 header
Content-Custom: m2 header
From: m2@example.com
Subject: m2
@ -61,7 +60,6 @@ m2 body
--foo--
epilogue
}}})
@ -82,7 +80,7 @@ Subject: m1
m1 body
--foo
X-Mime: m2 header
Content-Custom: m2 header
From: m2@example.com
Subject: m2
@ -91,7 +89,6 @@ m2 body
--foo--
epilogue
}}})
@ -117,7 +114,7 @@ Subject: m1
m1 body
--foo
X-Mime: m2 header
Content-Custom: m2 header
From: m2@example.com
Subject: m2
@ -125,9 +122,6 @@ Subject: m2
m2 body
--foo--
epilogue
}}})
ok fetch 1 (body.peek[1.1])
@ -170,7 +164,7 @@ m2 body
ok fetch 1 (body.peek[1.2.MIME])
* 1 fetch (body[1.2.MIME] {{{
X-Mime: m2 header
Content-Custom: m2 header
}}})

View file

@ -19,7 +19,7 @@ Subject: m1
m1 body
--foo
X-Mime: m2 header
Content-Custom: m2 header
From: m2@example.com
Subject: m2
@ -28,4 +28,3 @@ m2 body
--foo--
epilogue

View file

@ -6,8 +6,6 @@ ok search sentbefore 24-mar-2007
* search
ok search sentbefore 25-mar-2007
* search 1
ok search sentbefore 26-mar-2007
* search 1 2 3 4 5 6
ok search sentbefore 27-mar-2007
* search 1 2 3 4 5 6 7

View file

@ -1,80 +1,80 @@
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sat, 24 Mar 2007 23:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sat, 24 Mar 2007 23:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 25 Mar 2007 00:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 25 Mar 2007 00:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 25 Mar 2007 01:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 25 Mar 2007 01:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 25 Mar 2007 02:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 25 Mar 2007 02:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 25 Mar 2007 04:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 25 Mar 2007 04:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 25 Mar 2007 23:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 25 Mar 2007 23:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Mon, 26 Mar 2007 00:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Mon, 26 Mar 2007 00:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sat, 27 Oct 2007 03:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sat, 27 Oct 2007 03:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 00:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 00:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 01:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 01:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 02:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 02:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 03:00:00 +0300
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 03:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 03:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 03:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 04:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 04:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Sun, 28 Oct 2007 23:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Sun, 28 Oct 2007 23:00:00 +0000
body
From user@domain Sat Mar 24 23:00:00 2007 +0200
Date: Mon, 29 Oct 2007 00:00:00 +0200
From user@domain Sat Mar 24 23:00:00 2007 +0000
Date: Mon, 29 Oct 2007 00:00:00 +0000
body

View file

@ -4,20 +4,20 @@ messages: all
ok sort (from) us-ascii all
* sort 3 2 1
ok sort (to) us-ascii all
* sort 3 1 2
* sort 3 2 1
ok sort (cc) us-ascii all
* sort 3 1 2
* sort 2 1 3
ok sort (reverse from) us-ascii all
* sort 1 2 3
ok sort (reverse to) us-ascii all
* sort 1 2 3
ok sort (reverse cc) us-ascii all
* sort 1 2 3
* sort 3 1 2
ok sort (from reverse arrival) us-ascii all
* sort 3 2 1
ok sort (to reverse arrival) us-ascii all
* sort 3 2 1
ok sort (cc reverse arrival) us-ascii all
* sort 3 2 1
* sort 2 1 3

View file

@ -1,6 +1,6 @@
From user@domain Fri Feb 22 00:06:23 2008
From: user2@domain2.org
To: foo bar <user2@domain2.org>
To: user2@domain2.org
Cc: user2@domain2.org (foo bar)
1
@ -8,7 +8,7 @@ Cc: user2@domain2.org (foo bar)
From user@domain Fri Feb 22 01:06:23 2008
From: user2@domain1.org
To: user2@domain1.org
Cc: user2: blah@domain1.org;
Cc: blah@domain1.org
2

View file

@ -5,7 +5,7 @@ ok sort (date) us-ascii all
* sort 1 3 7 5 2 4 6
ok sort (reverse date) us-ascii all
* sort 2 4 6 5 3 7 1
* sort 6 4 2 5 7 3 1
ok sort (date reverse size) us-ascii all
* sort 1 7 3 5 6 4 2

View file

@ -19,6 +19,7 @@ Date: Fri, 22 Feb 2008 02:00:00 +0200
44
From user@domain Fri Feb 22 01:30:23 2008 +0200
Date: Fri, 22 Feb 2008 01:30:23 +0200
Subject: foo
55555
@ -29,6 +30,7 @@ Date: Fri, 22 Feb 2008 02:00:00 +0200
6666
From user@domain Fri Feb 22 01:00:00 2008 +0200
Date: Fri, 22 Feb 2008 01:00:00 +0200
Subject: foo bar foo bar foo bar fooo
777

View file

@ -2,7 +2,7 @@ capabilities: SORT=DISPLAY
messages: all
ok sort (displayto) us-ascii all
* sort 6 2 3 8 4 1 5 7
* sort 8 7 2 3 4 1 5 6
ok sort (reverse displayto) us-ascii all
* sort 7 5 1 4 8 3 2 6
* sort 6 5 1 4 3 2 7 8

View file

@ -2,10 +2,10 @@ capabilities: SORT
messages: all
ok sort (subject) us-ascii all
* sort 9 10 1 14 3 5 11 6 15 2 7 12 13 8 4
* sort 9 10 14 2 12 15 8 4 1 3 5 11 6 7 13
ok sort (reverse subject) us-ascii all
* sort 4 8 2 7 12 13 15 6 3 5 11 14 1 9 10
* sort 13 7 6 11 5 3 1 4 8 15 12 2 14 10 9
ok sort (subject reverse size) us-ascii all
* sort 10 9 1 14 11 5 3 6 15 13 12 7 2 8 4
* sort 10 9 14 12 2 15 8 4 1 11 5 3 6 13 7

View file

@ -2,10 +2,10 @@ capabilities: THREAD=REFERENCES
messages: all
ok thread references us-ascii all
* thread (3 2)(1)
* thread (1 2 3)
ok store 1 +flags \deleted
ok expunge
ok thread references us-ascii all
* thread (2 1)
* thread (1 2)

View file

@ -4,6 +4,6 @@ Message-Id: <a@b>
body
From user@domain Fri Feb 22 15:06:23 2008
Message-Id: <a@b>
Message-Id: <a@c>
body

View file

@ -6,7 +6,7 @@ body
From user@domain Fri Feb 22 15:06:24 2008
Message-Id: <b@b>
References: <c@b>
References: <a@b>
Subject: Re: foo
body

View file

@ -8,13 +8,13 @@ ok append
ok select $mailbox
ok thread references us-ascii all
* THREAD (1 (2 4)(3))
* THREAD (1 2 3 4)
ok store 1,2 +flags \deleted
ok expunge
ok thread references us-ascii all
* THREAD (1)(2)
* THREAD (1 2)
ok append
ok thread references us-ascii all
* THREAD (1)((2)(3))
* THREAD (1 2 3)

View file

@ -2,4 +2,4 @@ capabilities: THREAD=REFERENCES
messages: all
ok thread references us-ascii all
* THREAD ((1)(2))
* THREAD (1 2)

View file

@ -2,10 +2,10 @@ capabilities: THREAD=REFERENCES
messages: all
ok thread references us-ascii all
* thread (1 (2 3)(4))
* thread (1 2 3 4)
ok store 2 +flags \deleted
ok expunge
ok thread references us-ascii all
* thread (1 3 2)
* thread (1 2 3)

View file

@ -145,7 +145,9 @@ Content-Transfer-Encoding: Quoted-printable
--unique-boundary-1--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 1854
----------------------------------
BODY[HEADER] {239}
MIME-Version: 1.0
@ -269,6 +271,16 @@ next part.]
BODY[1.MIME] {2}
----------------------------------
BODY[1.1] {262}
... Some text appears here ...
[Note that the blank between the boundary and the start
of the text in this part means no header fields were
given and this is text in the US-ASCII character set.
It could have been done with explicit typing as in the
next part.]
----------------------------------
BODY[2] {111}
This could have been part of the previous part, but
@ -297,6 +309,12 @@ BODY[2.MIME] {45}
Content-Type: text/plain; charset=US-ASCII
----------------------------------
BODY[2.1] {111}
This could have been part of the previous part, but
illustrates explicit versus implicit typing of body
parts.
----------------------------------
BODY[3] {314}
--unique-boundary-2
@ -314,7 +332,9 @@ Content-Transfer-Encoding: base64
--unique-boundary-2--
BINARY.SIZE[3] 0
BINARY[3] {16}
[binary content]
BINARY.SIZE[3] 376
----------------------------------
BODY[3.HEADER] {62}
Content-Type: multipart/parallel; boundary=unique-boundary-2
@ -367,6 +387,11 @@ Content-Type: audio/basic
Content-Transfer-Encoding: base64
----------------------------------
BODY[3.1.1] {85}
... base64-encoded 8000 Hz single-channel
mu-law-format audio data goes here ...
----------------------------------
BODY[3.2] {44}
... base64-encoded image data goes here ...
@ -390,6 +415,10 @@ Content-Type: image/jpeg
Content-Transfer-Encoding: base64
----------------------------------
BODY[3.2.1] {44}
... base64-encoded image data goes here ...
----------------------------------
BODY[4] {140}
This is <bold><italic>enriched.</italic></bold>
@ -424,6 +453,14 @@ BODY[4.MIME] {30}
Content-Type: text/enriched
----------------------------------
BODY[4.1] {140}
This is <bold><italic>enriched.</italic></bold>
<smaller>as defined in RFC 1896</smaller>
Isn't it
<bigger><bigger>cool?</bigger></bigger>
----------------------------------
BODY[5] {223}
From: (mailbox in US-ASCII)
@ -451,11 +488,14 @@ BODY[5.TEXT] {48}
... Additional text in ISO-8859-1 goes here ...
----------------------------------
BODY[5.MIME] {91}
Content-Type: Text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: Quoted-printable
BODY[5.MIME] {31}
Content-Type: message/rfc822
----------------------------------
BODY[5.1] {48}
... Additional text in ISO-8859-1 goes here ...
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {79}
From: Nathaniel Borenstein <nsb@nsb.fv.com>

View file

@ -75,7 +75,9 @@ get RFC-MIME.DOC
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 1109
----------------------------------
BODY[HEADER] {198}
From: Whomever
@ -158,6 +160,11 @@ Content-Type: message/external-body; name="BodyFormats.ps";
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
----------------------------------
BODY[1.1] {79}
Content-type: application/postscript
Content-ID: <id42@guppylake.bellcore.com>
----------------------------------
BODY[2] {79}
Content-type: application/postscript
@ -187,6 +194,11 @@ Content-Type: message/external-body; access-type=local-file;
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
----------------------------------
BODY[2.1] {79}
Content-type: application/postscript
Content-ID: <id42@guppylake.bellcore.com>
----------------------------------
BODY[3] {97}
Content-type: application/postscript
@ -220,6 +232,13 @@ Content-Type: message/external-body;
expiration="Fri, 14 Jun 1991 19:13:14 -0400 (EDT)"
----------------------------------
BODY[3.1] {97}
Content-type: application/postscript
Content-ID: <id42@guppylake.bellcore.com>
get RFC-MIME.DOC
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {29}
From: Whomever

View file

@ -5,7 +5,7 @@ BODY (
) NIL NIL "7bit" 61 5
) (
"message" "rfc822" NIL NIL NIL "7bit" 1979 (
"Thu, 13 Aug 1998 07:42:41 +0000" "Map of Argentina with Description" (
"Thu, 13 Aug 1998 17:42:41 +1000" "Map of Argentina with Description" (
(
"Bill Clinton" NIL "president" "whitehouse.gov"
)
@ -43,7 +43,7 @@ BODYSTRUCTURE (
) NIL NIL "7bit" 61 5 "63aa55d7eacd3e7d4af551d3d7f8fe46" NIL NIL NIL
) (
"message" "rfc822" NIL NIL NIL "7bit" 1979 (
"Thu, 13 Aug 1998 07:42:41 +0000" "Map of Argentina with Description" (
"Thu, 13 Aug 1998 17:42:41 +1000" "Map of Argentina with Description" (
(
"Bill Clinton" NIL "president" "whitehouse.gov"
)
@ -161,7 +161,9 @@ U6ZGxseyk8SasGw3J9GRzdTQky1iHNvcPNNI4TLeKdfMvy0vMqLrItvuxfDW8ubjueDtJufz
--D7F------------D7FD5A0B8AB9C65CCDBFA872--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 2652
----------------------------------
BODY[HEADER] {270}
From: Al Gore <vice-president@whitehouse.gov>
@ -283,6 +285,14 @@ Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
----------------------------------
BODY[1.1] {61}
Fred,
Fire up Air Force One! We're going South!
Thanks,
Al
----------------------------------
BODY[2] {1979}
Return-Path: <president@whitehouse.gov>
@ -390,9 +400,10 @@ U6ZGxseyk8SasGw3J9GRzdTQky1iHNvcPNNI4TLeKdfMvy0vMqLrItvuxfDW8ubjueDtJufz
--DC8------------DC8638F443D87A7F0726DEF7--
----------------------------------
BODY[2.MIME] {98}
Content-Type: multipart/mixed;
boundary="DC8------------DC8638F443D87A7F0726DEF7"
BODY[2.MIME] {91}
Content-Type: message/rfc822
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
----------------------------------
@ -452,6 +463,21 @@ Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
----------------------------------
BODY[2.1.1] {355}
Hi A1,
I finally figured out this MIME thing. Pretty cool. I'll send you
some sax music in .au files next week!
Anyway, the attached image is really too small to get a good look at
Argentina. Try this for a much better map:
http://www.1one1yp1anet.com/dest/sam/graphics/map-arg.htm
Then again, shouldn't the CIA have something like that?
Bill
----------------------------------
BODY[2.2] {389}
R01GOD1hJQA1AKIAAP/////78P/omn19fQAAAAAAAAAAAAAAACwAAAAAJQA1AAAD7Qi63P5w
@ -485,6 +511,14 @@ Content-Transfer-Encoding: base64
Content-Disposition: inline; fi1ename="map_of_Argentina.gif"
----------------------------------
BODY[2.2.1] {389}
R01GOD1hJQA1AKIAAP/////78P/omn19fQAAAAAAAAAAAAAAACwAAAAAJQA1AAAD7Qi63P5w
wEmjBCLrnQnhYCgM1wh+pkgqqeC9XrutmBm7hAK3tP31gFcAiFKVQrGFR6kscnonTe7FAAad
GugmRu3CmiBt57fsVq3Y0VFKnpYdxPC6M7Ze4crnnHum4oN6LFJ1bn5NXTN7OF5fQkN5WYow
BEN2dkGQGWJtSzqGTICJgnQuTJN/WJsojad9qXMuhIWdjXKjY4tenjo6tjVssk2gaWq3uGNX
U6ZGxseyk8SasGw3J9GRzdTQky1iHNvcPNNI4TLeKdfMvy0vMqLrItvuxfDW8ubjueDtJufz
7itICBxISKDBgwgTKjyYAAA7
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {125}
From: Al Gore <vice-president@whitehouse.gov>

View file

@ -55,7 +55,9 @@ Content-Type: application/x-whatever
--boundary42--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 565
----------------------------------
BODY[HEADER] {228}
From: Nathaniel Borenstein <nsb@bellcore.com>
@ -114,6 +116,10 @@ BODY[1.MIME] {45}
Content-Type: text/plain; charset=us-ascii
----------------------------------
BODY[1.1] {48}
... plain text version of message goes here ...
----------------------------------
BODY[2] {69}
... RFC 1896 text/enriched version of same message
@ -139,6 +145,11 @@ BODY[2.MIME] {30}
Content-Type: text/enriched
----------------------------------
BODY[2.1] {69}
... RFC 1896 text/enriched version of same message
goes here ...
----------------------------------
BODY[3] {51}
... fanciest version of same message goes here ...
@ -160,6 +171,10 @@ BODY[3.MIME] {39}
Content-Type: application/x-whatever
----------------------------------
BODY[3.1] {51}
... fanciest version of same message goes here ...
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {81}
From: Nathaniel Borenstein <nsb@bellcore.com>

View file

@ -6,7 +6,7 @@ BODY (
) (
(
"message" NIL NIL NIL NIL NIL 100 (
"Fri, 26 Mar 1993 09:13:32 +0000" "my opinion" NIL NIL NIL NIL NIL NIL NIL NIL
"Fri, 26 Mar 1993 11:13:32 +0200" "my opinion" NIL NIL NIL NIL NIL NIL NIL NIL
) (
"text" "plain" (
"charset" "us-ascii"
@ -14,7 +14,7 @@ BODY (
) 0
) (
"message" NIL NIL NIL NIL NIL 125 (
"Fri, 26 Mar 1993 15:07:13 +0000" "my different opinion" NIL NIL NIL NIL NIL NIL NIL NIL
"Fri, 26 Mar 1993 10:07:13 -0500" "my different opinion" NIL NIL NIL NIL NIL NIL NIL NIL
) (
"text" "plain" (
"charset" "us-ascii"
@ -32,7 +32,7 @@ BODYSTRUCTURE (
) (
(
"message" NIL NIL NIL NIL NIL 100 (
"Fri, 26 Mar 1993 09:13:32 +0000" "my opinion" NIL NIL NIL NIL NIL NIL NIL NIL
"Fri, 26 Mar 1993 11:13:32 +0200" "my opinion" NIL NIL NIL NIL NIL NIL NIL NIL
) (
"text" "plain" (
"charset" "us-ascii"
@ -40,7 +40,7 @@ BODYSTRUCTURE (
) 0 "ef1527984c599523c90fb184a8fdfd61" NIL NIL NIL
) (
"message" NIL NIL NIL NIL NIL 125 (
"Fri, 26 Mar 1993 15:07:13 +0000" "my different opinion" NIL NIL NIL NIL NIL NIL NIL NIL
"Fri, 26 Mar 1993 10:07:13 -0500" "my different opinion" NIL NIL NIL NIL NIL NIL NIL NIL
) (
"text" "plain" (
"charset" "us-ascii"
@ -92,7 +92,9 @@ Subject: my different opinion
------ main boundary ------
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 728
----------------------------------
BODY[HEADER] {214}
From: Moderator-Address
@ -161,6 +163,10 @@ BODY[1.TEXT] {45}
BODY[1.MIME] {2}
----------------------------------
BODY[1.1] {45}
...Introductory text or table of contents...
----------------------------------
BODY[2] {306}
------ next message ----
@ -181,7 +187,9 @@ Subject: my different opinion
------ next message ------
BINARY.SIZE[2] 0
BINARY[2] {16}
[binary content]
BINARY.SIZE[2] 385
----------------------------------
BODY[2.HEADER] {79}
Content-Type: multipart/digest;
@ -240,6 +248,10 @@ BODY[2.1.TEXT] {22}
BODY[2.1.MIME] {2}
----------------------------------
BODY[2.1.1] {22}
...body goes here ...
----------------------------------
BODY[2.2] {125}
From: someone-else-again
@ -266,6 +278,10 @@ BODY[2.2.TEXT] {31}
BODY[2.2.MIME] {2}
----------------------------------
BODY[2.2.1] {31}
... another body goes here ...
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {45}
From: Moderator-Address

View file

@ -51,7 +51,9 @@ It DOES end with a linebreak.
This is the epilogue. It is also to be ignored.
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 691
----------------------------------
BODY[HEADER] {224}
From: Nathaniel Borenstein <nsb@bellcore.com>
@ -108,6 +110,10 @@ It does NOT end with a linebreak.
BODY[1.MIME] {2}
----------------------------------
BODY[1.1] {79}
This is implicitly typed plain US-ASCII text.
It does NOT end with a linebreak.
----------------------------------
BODY[2] {76}
This is explicitly typed plain US-ASCII text.
@ -133,6 +139,11 @@ BODY[2.MIME] {45}
Content-Type: text/plain; charset=us-ascii
----------------------------------
BODY[2.1] {76}
This is explicitly typed plain US-ASCII text.
It DOES end with a linebreak.
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {81}
From: Nathaniel Borenstein <nsb@bellcore.com>

View file

@ -57,7 +57,9 @@ Content-Disposition: inline
--boundary-string--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 617
----------------------------------
BODY[HEADER] {149}
From: sender@example.com
@ -121,6 +123,11 @@ Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
----------------------------------
BODY[1.1] {87}
Plain text email goes here!
This is the fallback if email client does not support HTML
----------------------------------
BODY[2] {93}
<h1>This is the HTML Section!</h1>
@ -150,6 +157,11 @@ Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
----------------------------------
BODY[2.1] {93}
<h1>This is the HTML Section!</h1>
<p>This is what displays in most modern email clients</p>
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {53}
From: sender@example.com

View file

@ -203,7 +203,9 @@ K
--1--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 871
----------------------------------
BODY[HEADER] {82}
Subject: RFC 8621 Section 4.1.4 test
@ -309,6 +311,9 @@ Content-Type: text/plain
Content-Disposition: inline
----------------------------------
BODY[1.1] {1}
A
----------------------------------
BODY[2] {608}
--2
@ -366,7 +371,9 @@ Subject: J
J
--2--
BINARY.SIZE[2] 0
BINARY[2] {16}
[binary content]
BINARY.SIZE[2] 653
----------------------------------
BODY[2.HEADER] {45}
Content-Type: multipart/mixed; boundary="2"
@ -471,7 +478,9 @@ F
--3--
BINARY.SIZE[2.1] 0
BINARY[2.1] {16}
[binary content]
BINARY.SIZE[2.1] 437
----------------------------------
BODY[2.1.HEADER] {51}
Content-Type: multipart/alternative; boundary="3"
@ -538,7 +547,9 @@ Content-Disposition: inline
D
--4--
BINARY.SIZE[2.1.1] 0
BINARY[2.1.1] {16}
[binary content]
BINARY.SIZE[2.1.1] 235
----------------------------------
BODY[2.1.1.HEADER] {45}
Content-Type: multipart/mixed; boundary="4"
@ -589,6 +600,9 @@ Content-Type: text/plain
Content-Disposition: inline
----------------------------------
BODY[2.1.1.1.1] {1}
B
----------------------------------
BODY[2.1.1.2] {1}
C
@ -610,6 +624,9 @@ Content-Type: image/jpeg
Content-Disposition: inline
----------------------------------
BODY[2.1.1.2.1] {1}
C
----------------------------------
BODY[2.1.1.3] {1}
D
@ -631,6 +648,9 @@ Content-Type: text/plain
Content-Disposition: inline
----------------------------------
BODY[2.1.1.3.1] {1}
D
----------------------------------
BODY[2.1.2] {86}
--5
@ -643,7 +663,9 @@ Content-Type: image/jpeg
F
--5--
BINARY.SIZE[2.1.2] 0
BINARY[2.1.2] {16}
[binary content]
BINARY.SIZE[2.1.2] 133
----------------------------------
BODY[2.1.2.HEADER] {47}
Content-Type: multipart/related; boundary="5"
@ -685,6 +707,9 @@ BODY[2.1.2.1.MIME] {26}
Content-Type: text/html
----------------------------------
BODY[2.1.2.1.1] {14}
<html>E</html>
----------------------------------
BODY[2.1.2.2] {1}
F
@ -704,6 +729,9 @@ BODY[2.1.2.2.MIME] {27}
Content-Type: image/jpeg
----------------------------------
BODY[2.1.2.2.1] {1}
F
----------------------------------
BODY[2.2] {1}
G
@ -725,6 +753,9 @@ Content-Type: image/jpeg
Content-Disposition: attachment
----------------------------------
BODY[2.2.1] {1}
G
----------------------------------
BODY[2.3] {1}
H
@ -744,6 +775,9 @@ BODY[2.3.MIME] {36}
Content-Type: application/x-excel
----------------------------------
BODY[2.3.1] {1}
H
----------------------------------
BODY[2.4] {13}
Subject: J
@ -761,9 +795,13 @@ Subject: J
BODY[2.4.TEXT] {1}
J
----------------------------------
BODY[2.4.MIME] {2}
BODY[2.4.MIME] {31}
Content-Type: message/rfc822
----------------------------------
BODY[2.4.1] {1}
J
----------------------------------
BODY[3] {1}
K
@ -785,6 +823,9 @@ Content-Type: text/plain
Content-Disposition: inline
----------------------------------
BODY[3.1] {1}
K
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {2}

View file

@ -5,7 +5,7 @@ BODY (
) NIL NIL "7bit" 54 0
) (
"message" "rfc822" NIL NIL NIL "base64" 1179 (
"Tue, 14 Dec 2021 10:48:25 +0000" "HTML test" (
"Tue, 14 Dec 2021 11:48:25 +0100" "HTML test" (
(
"Name" NIL "email" "example.com"
)
@ -43,7 +43,7 @@ BODYSTRUCTURE (
) NIL NIL "7bit" 54 0 "e377afc895a2c4c0d17b378f355de59e" NIL NIL NIL
) (
"message" "rfc822" NIL NIL NIL "base64" 1179 (
"Tue, 14 Dec 2021 10:48:25 +0000" "HTML test" (
"Tue, 14 Dec 2021 11:48:25 +0100" "HTML test" (
(
"Name" NIL "email" "example.com"
)
@ -114,7 +114,9 @@ c2FnZQ0KICA8L2JvZHk+DQo8L2h0bWw+DQoNCi0tYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
YWFhYWFhYWFhYWFhYS0tDQo=
--bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 1649
----------------------------------
BODY[HEADER] {83}
Content-Type: multipart/mixed;
@ -178,6 +180,9 @@ Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
----------------------------------
BODY[1.1] {54}
This is a message with a base64 encoded attached email
----------------------------------
BODY[2] {1179}
VG86ICJlbWFpbEBleGFtcGxlLmNvbSIgPGVtYWlsQGV4YW1wbGUuY29tPg0KRnJvbTogTmFtZSA8
@ -236,10 +241,10 @@ Content-Transfer-Encoding: 7bit
--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--
----------------------------------
BODY[2.MIME] {119}
Content-Type: multipart/alternative;
boundary="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Content-Language: en-US
BODY[2.MIME] {128}
Content-Disposition: attachment; filename="attached_email.eml"
Content-Type: message/rfc822
Content-Transfer-Encoding: base64
----------------------------------
@ -263,6 +268,9 @@ Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
----------------------------------
BODY[2.1.1] {30}
This is an *HTML* test message
----------------------------------
BODY[2.2] {173}
<html>
@ -308,6 +316,17 @@ Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit
----------------------------------
BODY[2.2.1] {173}
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
This is an <b>HTML</b> test message
</body>
</html>
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {2}

View file

@ -115,7 +115,9 @@ R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
--giddyup--
--festivus--
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 1457
----------------------------------
BODY[HEADER] {349}
From: Art Vandelay <art@vandelay.com> (Vandelay Industries)
@ -193,6 +195,12 @@ Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: base64
----------------------------------
BODY[1.1] {239}
PGh0bWw+PHA+SSB3YXMgdGhpbmtpbmcgYWJvdXQgcXVpdHRpbmcgdGhlICZsZHF1bztle
HBvcnRpbmcmcmRxdW87IHRvIGZvY3VzIGp1c3Qgb24gdGhlICZsZHF1bztpbXBvcnRpbm
cmcmRxdW87LDwvcD48cD5idXQgdGhlbiBJIHRob3VnaHQsIHdoeSBub3QgZG8gYm90aD8
gJiN4MjYzQTs8L3A+PC9odG1sPg==
----------------------------------
BODY[2] {723}
From: "Cosmo Kramer" <kramer@kramerica.com>
@ -244,8 +252,8 @@ Content-Disposition: attachment
R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
--giddyup--
----------------------------------
BODY[2.MIME] {53}
Content-Type: multipart/mixed; boundary="giddyup";
BODY[2.MIME] {31}
Content-Type: message/rfc822
----------------------------------
@ -275,6 +283,12 @@ Content-Type: text/plain; charset="utf-16"
Content-Transfer-Encoding: quoted-printable
----------------------------------
BODY[2.1.1] {228}
=FF=FE=0C!5=D8"=DD5=D8)=DD5=D8-=DD =005=D8*=DD5=D8"=DD =005=D8"=
=DD5=D85=DD5=D8-=DD5=D8,=DD5=D8/=DD5=D81=DD =005=D8*=DD5=D86=DD =
=005=D8=1F=DD5=D8,=DD5=D8,=DD5=D8(=DD =005=D8-=DD5=D8)=DD5=D8"=
=DD5=D8=1E=DD5=D80=DD5=D8"=DD!=00
----------------------------------
BODY[2.2] {56}
R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
@ -300,6 +314,9 @@ Content-Transfer-Encoding: Base64
Content-Disposition: attachment
----------------------------------
BODY[2.2.1] {56}
R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {196}
From: Art Vandelay <art@vandelay.com> (Vandelay Industries)

View file

@ -1,6 +1,6 @@
BODY (
"message" "rfc822" NIL NIL NIL NIL 88 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -22,7 +22,7 @@ BODY (
BODYSTRUCTURE (
"message" "rfc822" NIL NIL NIL NIL 88 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -98,9 +98,14 @@ BODY[1.TEXT] {12}
Hello world
----------------------------------
BODY[1.MIME] {2}
BODY[1.MIME] {31}
Content-Type: message/rfc822
----------------------------------
BODY[1.1] {12}
Hello world
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {24}
From: user@domain.org

View file

@ -1,6 +1,6 @@
BODY (
"message" "rfc822" NIL NIL NIL NIL 271 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -60,7 +60,7 @@ BODY (
BODYSTRUCTURE (
"message" "rfc822" NIL NIL NIL NIL 271 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -253,8 +253,8 @@ m2 body
--foo--
----------------------------------
BODY[1.MIME] {49}
Content-Type: multipart/digest; boundary="foo"
BODY[1.MIME] {31}
Content-Type: message/rfc822
----------------------------------
@ -278,6 +278,10 @@ m1 body
BODY[1.1.MIME] {2}
----------------------------------
BODY[1.1.1] {8}
m1 body
----------------------------------
BODY[1.2] {42}
From: m2@example.com
@ -299,6 +303,10 @@ m2 body
BODY[1.2.MIME] {2}
----------------------------------
BODY[1.2.1] {8}
m2 body
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {24}
From: user@domain.org

View file

@ -5,7 +5,7 @@ BODY (
) NIL NIL "7bit" 6 1
) (
"message" "rfc822" NIL NIL NIL NIL 280 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -39,7 +39,7 @@ BODYSTRUCTURE (
) NIL NIL "7bit" 6 1 "b1946ac92492d2347c6235b4d2611184" NIL NIL NIL
) (
"message" "rfc822" NIL NIL NIL NIL 280 (
"Sun, 12 Aug 2012 09:34:56 +0000" "submsg" (
"Sun, 12 Aug 2012 12:34:56 +0300" "submsg" (
(
NIL NIL "sub" "domain.org"
)
@ -109,7 +109,9 @@ Sub MIME epilogue
--foo bar--
Root MIME epilogue
BINARY.SIZE[] 0
BINARY[] {16}
[binary content]
BINARY.SIZE[] 565
----------------------------------
BODY[HEADER] {130}
From: user@domain.org
@ -181,6 +183,10 @@ BODY[1.MIME] {47}
Content-Type: text/x-myown; charset=us-ascii
----------------------------------
BODY[1.1] {6}
hello
----------------------------------
BODY[2] {280}
From: sub@domain.org
@ -230,8 +236,8 @@ Hello another world
Sub MIME epilogue
----------------------------------
BODY[2.MIME] {55}
Content-Type: multipart/alternative; boundary="sub1"
BODY[2.MIME] {31}
Content-Type: message/rfc822
----------------------------------
@ -256,6 +262,10 @@ BODY[2.1.MIME] {26}
Content-Type: text/html
----------------------------------
BODY[2.1.1] {19}
<p>Hello world</p>
----------------------------------
BODY[2.2] {20}
Hello another world
@ -278,6 +288,10 @@ BODY[2.2.MIME] {27}
Content-Type: text/plain
----------------------------------
BODY[2.2.1] {20}
Hello another world
----------------------------------
BODY[HEADER.FIELDS (FROM TO)] {24}
From: user@domain.org

View file

@ -74,7 +74,7 @@
{
"partId": "2",
"blobId": "blob_0",
"size": 129,
"size": 131,
"headers": [
{
"name": "Content-Language",
@ -182,7 +182,7 @@
{
"partId": "2",
"blobId": "blob_0",
"size": 129,
"size": 131,
"headers": [
{
"name": "Content-Language",

View file

@ -159,7 +159,7 @@ member-of = ["sales"]
[[directory."local".users]]
name = "jane"
description = "Jane Doe"
secret = "abcde"
secret = "12345"
email = "jane@example.org"
email-list = ["info@example.org"]
member-of = ["sales", "support"]
@ -167,7 +167,7 @@ member-of = ["sales", "support"]
[[directory."local".users]]
name = "bill"
description = "Bill Foobar"
secret = "$2y$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe"
secret = "12345"
quota = 500000
email = "bill@example.org"
email-list = ["info@example.org"]