imap: use parse_message_id from mimeparser

This commit is contained in:
Alexander Krotov
2020-02-22 02:20:32 +03:00
committed by holger krekel
parent 33463856c5
commit 3c342339a1
2 changed files with 18 additions and 38 deletions

View File

@@ -1306,17 +1306,6 @@ fn precheck_imf(context: &Context, rfc724_mid: &str, server_folder: &str, server
} }
} }
fn parse_message_id(value: &str) -> crate::error::Result<String> {
let ids = mailparse::msgidparse(value)
.map_err(|err| format_err!("failed to parse message id {:?}", err))?;
if ids.len() == 1 {
Ok(ids[0].clone())
} else {
bail!("could not parse message_id: {}", value);
}
}
fn get_fetch_headers(prefetch_msg: &Fetch) -> Result<Vec<mailparse::MailHeader>> { fn get_fetch_headers(prefetch_msg: &Fetch) -> Result<Vec<mailparse::MailHeader>> {
let header_bytes = match prefetch_msg.header() { let header_bytes = match prefetch_msg.header() {
Some(header_bytes) => header_bytes, Some(header_bytes) => header_bytes,
@@ -1328,7 +1317,7 @@ fn get_fetch_headers(prefetch_msg: &Fetch) -> Result<Vec<mailparse::MailHeader>>
fn prefetch_get_message_id(headers: &[mailparse::MailHeader]) -> Result<String> { fn prefetch_get_message_id(headers: &[mailparse::MailHeader]) -> Result<String> {
if let Some(message_id) = headers.get_header_value(HeaderDef::MessageId)? { if let Some(message_id) = headers.get_header_value(HeaderDef::MessageId)? {
Ok(parse_message_id(&message_id)?) Ok(crate::mimeparser::parse_message_id(&message_id)?)
} else { } else {
Err(Error::Other("prefetch: No message ID found".to_string())) Err(Error::Other("prefetch: No message ID found".to_string()))
} }
@@ -1384,20 +1373,3 @@ fn prefetch_should_download(
let show = show && !blocked_contact; let show = show && !blocked_contact;
Ok(show) Ok(show)
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_message_id() {
assert_eq!(
parse_message_id("Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org").unwrap(),
"Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org"
);
assert_eq!(
parse_message_id("<Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org>").unwrap(),
"Mr.PRUe8HJBoaO.3whNvLCMFU0@testrun.org"
);
}
}

View File

@@ -741,7 +741,7 @@ impl MimeMessage {
pub fn get_rfc724_mid(&self) -> Option<String> { pub fn get_rfc724_mid(&self) -> Option<String> {
self.get(HeaderDef::MessageId) self.get(HeaderDef::MessageId)
.and_then(|msgid| parse_message_id(msgid)) .and_then(|msgid| parse_message_id(msgid).ok())
} }
fn merge_headers(headers: &mut HashMap<String, String>, fields: &[mailparse::MailHeader<'_>]) { fn merge_headers(headers: &mut HashMap<String, String>, fields: &[mailparse::MailHeader<'_>]) {
@@ -779,14 +779,16 @@ impl MimeMessage {
.get_header_value(HeaderDef::OriginalMessageId) .get_header_value(HeaderDef::OriginalMessageId)
.ok() .ok()
.flatten() .flatten()
.and_then(|v| parse_message_id(&v)) .and_then(|v| parse_message_id(&v).ok())
{ {
let additional_message_ids = report_fields let additional_message_ids = report_fields
.get_header_value(HeaderDef::AdditionalMessageIds) .get_header_value(HeaderDef::AdditionalMessageIds)
.ok() .ok()
.flatten() .flatten()
.map_or_else(Vec::new, |v| { .map_or_else(Vec::new, |v| {
v.split(' ').filter_map(parse_message_id).collect() v.split(' ')
.filter_map(|s| parse_message_id(s).ok())
.collect()
}); });
return Ok(Some(Report { return Ok(Some(Report {
@@ -909,14 +911,20 @@ pub(crate) struct Report {
additional_message_ids: Vec<String>, additional_message_ids: Vec<String>,
} }
fn parse_message_id(field: &str) -> Option<String> { pub(crate) fn parse_message_id(value: &str) -> crate::error::Result<String> {
if let Ok(addrs) = mailparse::addrparse(field) { let ids = mailparse::msgidparse(value)
// Assume the message id is a single id in the form of <id> .map_err(|err| format_err!("failed to parse message id {:?}", err))?;
if let mailparse::MailAddr::Single(mailparse::SingleInfo { ref addr, .. }) = addrs[0] {
return Some(addr.clone()); if ids.len() == 1 {
let id = &ids[0];
if id.starts_with('<') && id.ends_with('>') {
Ok(id.chars().skip(1).take(id.len() - 2).collect())
} else {
bail!("message-ID {} is not enclosed in < and >", value);
} }
} else {
bail!("could not parse message_id: {}", value);
} }
None
} }
fn is_known(key: &str) -> bool { fn is_known(key: &str) -> bool {