server: handle application/* as an attachment
This commit is contained in:
@@ -87,6 +87,7 @@ pub fn extract_body(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Body,
|
||||
// APPLICATION_ZIP and APPLICATION_GZIP are handled in the thread function
|
||||
APPLICATION_ZIP => extract_unhandled(m),
|
||||
APPLICATION_GZIP => extract_unhandled(m),
|
||||
mt if mt.starts_with("application/") => Ok(Body::text("".to_string())),
|
||||
_ => extract_unhandled(m),
|
||||
};
|
||||
if let Err(err) = ret {
|
||||
@@ -362,7 +363,7 @@ pub fn extract_mixed(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Body
|
||||
.subparts
|
||||
.iter()
|
||||
.map(|sp| sp.ctype.mimetype.as_str())
|
||||
.filter(|mt| !handled_types.contains(mt))
|
||||
.filter(|mt| !handled_types.contains(mt) && !mt.starts_with("application/"))
|
||||
.collect();
|
||||
unhandled_types.sort();
|
||||
if !unhandled_types.is_empty() {
|
||||
@@ -434,7 +435,11 @@ pub fn extract_mixed(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Body
|
||||
)));
|
||||
}
|
||||
}
|
||||
mt => parts.push(unhandled_html(MULTIPART_MIXED, mt)),
|
||||
mt => {
|
||||
if !mt.starts_with("application/") {
|
||||
parts.push(unhandled_html(MULTIPART_MIXED, mt))
|
||||
}
|
||||
}
|
||||
}
|
||||
part_addr.pop();
|
||||
}
|
||||
@@ -500,7 +505,7 @@ pub fn extract_related(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Bo
|
||||
.subparts
|
||||
.iter()
|
||||
.map(|sp| sp.ctype.mimetype.as_str())
|
||||
.filter(|mt| !handled_types.contains(mt))
|
||||
.filter(|mt| !handled_types.contains(mt) && !mt.starts_with("application/"))
|
||||
.collect();
|
||||
unhandled_types.sort();
|
||||
if !unhandled_types.is_empty() {
|
||||
@@ -580,6 +585,13 @@ pub fn walk_attachments_inner<T, F: Fn(&ParsedMail, &[usize]) -> Option<T> + Cop
|
||||
// get the bytes for serving attachments of HTTP
|
||||
pub fn extract_attachments(m: &ParsedMail, id: &str) -> Result<Vec<Attachment>, ServerError> {
|
||||
let mut attachments = Vec::new();
|
||||
|
||||
if m.ctype.mimetype.starts_with("application/") {
|
||||
if let Some(attachment) = extract_attachment(m, id, &[]) {
|
||||
attachments.push(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx, sp) in m.subparts.iter().enumerate() {
|
||||
if let Some(attachment) = extract_attachment(sp, id, &[idx]) {
|
||||
// Filter out inline attachements, they're flattened into the body of the message.
|
||||
@@ -602,12 +614,30 @@ pub fn extract_attachment(m: &ParsedMail, id: &str, idx: &[usize]) -> Option<Att
|
||||
pct.map(|pct| pct.params.get("name").map(|f| f.clone())),
|
||||
) {
|
||||
// Use filename from Content-Disposition
|
||||
(Some(filename), _) => filename,
|
||||
(Some(filename), _) => Some(filename),
|
||||
// Use filename from Content-Type
|
||||
(_, Some(Some(name))) => name,
|
||||
// No known filename, assume it's not an attachment
|
||||
_ => return None,
|
||||
(_, Some(Some(name))) => Some(name),
|
||||
// No known filename
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let filename = if let Some(fname) = filename {
|
||||
fname
|
||||
} else {
|
||||
if m.ctype.mimetype.starts_with("application/") {
|
||||
// Generate a default filename
|
||||
format!(
|
||||
"attachment-{}",
|
||||
idx.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(".")
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
info!("filename {}", filename);
|
||||
|
||||
// TODO: grab this from somewhere
|
||||
|
||||
Reference in New Issue
Block a user