use of com.zimbra.cs.mime.MPartInfo in project zm-mailbox by Zimbra.
the class ImapMessage method serializeStructure.
static void serializeStructure(PrintStream ps, MimeMessage root, boolean extensions) throws IOException, MessagingException {
LinkedList<LinkedList<MPartInfo>> queue = new LinkedList<LinkedList<MPartInfo>>();
LinkedList<MPartInfo> level = new LinkedList<MPartInfo>();
level.add(Mime.getParts(root).get(0));
queue.add(level);
boolean pop = false;
while (!queue.isEmpty()) {
level = queue.getLast();
if (level.isEmpty()) {
queue.removeLast();
pop = true;
continue;
}
MPartInfo mpi = level.getFirst();
MimePart mp = mpi.getMimePart();
boolean hasChildren = mpi.getChildren() != null && !mpi.getChildren().isEmpty();
// we used to force unset charsets on text/plain parts to US-ASCII, but that always seemed unwise...
ContentType ctype = new ContentType(mp.getHeader("Content-Type", null)).setContentType(mpi.getContentType());
String primary = nATOM(ctype.getPrimaryType()), subtype = nATOM(ctype.getSubType());
if (!pop)
ps.write('(');
if (primary.equals("\"MULTIPART\"")) {
if (!pop) {
// list is the multipart subtype (mixed, digest, parallel, alternative, etc.)."
if (!hasChildren) {
ps.print("NIL");
} else {
queue.addLast(new LinkedList<MPartInfo>(mpi.getChildren()));
continue;
}
}
ps.write(' ');
ps.print(subtype);
if (extensions) {
// 7.4.2: "Extension data follows the multipart subtype. Extension data is never
// returned with the BODY fetch, but can be returned with a BODYSTRUCTURE
// fetch. Extension data, if present, MUST be in the defined order. The
// extension data of a multipart body part are in the following order:
// body parameter parenthesized list, body disposition, body language,
// body location"
ps.write(' ');
nparams(ps, ctype);
ps.write(' ');
ndisposition(ps, mp.getHeader("Content-Disposition", null));
ps.write(' ');
nlist(ps, mp.getContentLanguage());
ps.write(' ');
nstring(ps, mp.getHeader("Content-Location", null));
}
} else {
if (!pop) {
// 7.4.2: "The basic fields of a non-multipart body part are in the following order:
// body type, body subtype, body parameter parenthesized list, body id, body
// description, body encoding, body size."
String cte = mp.getEncoding();
cte = (cte == null || cte.trim().equals("") ? "7bit" : cte);
aSTRING(ps, ctype.getPrimaryType());
ps.write(' ');
aSTRING(ps, ctype.getSubType());
ps.write(' ');
nparams(ps, ctype);
ps.write(' ');
nstring(ps, mp.getContentID());
ps.write(' ');
nstring2047(ps, mp.getDescription());
ps.write(' ');
aSTRING(ps, cte);
ps.write(' ');
ps.print(Math.max(mp.getSize(), 0));
}
boolean rfc822 = primary.equals("\"MESSAGE\"") && subtype.equals("\"RFC822\"");
if (rfc822) {
// size in text lines of the encapsulated message."
if (!pop) {
if (!hasChildren) {
ps.print(" NIL NIL");
} else {
MimeMessage mm = (MimeMessage) mpi.getChildren().get(0).getMimePart();
ps.write(' ');
serializeEnvelope(ps, mm);
ps.write(' ');
queue.addLast(new LinkedList<MPartInfo>(mpi.getChildren()));
continue;
}
}
ps.write(' ');
ps.print(getLineCount(mp));
} else if (primary.equals("\"TEXT\"")) {
// 7.4.2: "A body type of type TEXT contains, immediately after the basic fields, the
// size of the body in text lines. Note that this size is the size in its
// content transfer encoding and not the resulting size after any decoding."
ps.write(' ');
ps.print(getLineCount(mp));
}
if (extensions) {
// 7.4.2: "Extension data follows the basic fields and the type-specific fields
// listed above. Extension data is never returned with the BODY fetch,
// but can be returned with a BODYSTRUCTURE fetch. Extension data, if
// present, MUST be in the defined order. The extension data of a
// non-multipart body part are in the following order: body MD5, body
// disposition, body language, body location"
ps.write(' ');
nstring(ps, mp.getContentMD5());
ps.write(' ');
ndisposition(ps, mp.getHeader("Content-Disposition", null));
ps.write(' ');
nlist(ps, mp.getContentLanguage());
ps.write(' ');
nstring(ps, mp.getHeader("Content-Location", null));
}
}
ps.write(')');
level.removeFirst();
pop = false;
}
}
use of com.zimbra.cs.mime.MPartInfo in project zm-mailbox by Zimbra.
the class Invite method addInlineATTACHes.
protected ZComponent addInlineATTACHes(ZComponent comp) {
MimeMessage mimeMsg = null;
try {
mimeMsg = getMimeMessage();
} catch (ServiceException e1) {
return comp;
}
if (mimeMsg == null) {
return comp;
}
try {
List<MPartInfo> parts = Mime.getParts(mimeMsg, MimeConstants.P_CHARSET_UTF8);
if (parts != null && !parts.isEmpty()) {
for (MPartInfo body : parts.get(0).getChildren()) {
if (body.isMultipart()) {
continue;
}
MimePart mp = body.getMimePart();
String ctype = StringUtil.stripControlCharacters(body.getContentType());
if (MimeConstants.CT_TEXT_CALENDAR.equalsIgnoreCase(ctype)) {
// Otherwise it's just an attachment that happens to be a .ics file.
try {
ContentType ct = new ContentType(body.getMimePart().getContentType());
if (ct.getParameter("method") != null) {
continue;
}
} catch (MessagingException e) {
}
}
String contentType = StringUtil.stripControlCharacters(body.getContentType());
String fileName = Mime.getFilename(mp);
try (InputStream in = mp.getInputStream()) {
byte[] rawBytes = IOUtils.toByteArray(in);
Attach attachment = Attach.fromUnencodedAndContentType(rawBytes, contentType);
if (!Strings.isNullOrEmpty(fileName)) {
attachment.setFileName(fileName);
}
comp.addProperty(attachment.toZProperty());
}
}
}
} catch (MessagingException | IOException e) {
ZimbraLog.calendar.warn("Problem adding inline ATTACHes", e);
}
return comp;
}
use of com.zimbra.cs.mime.MPartInfo in project zm-mailbox by Zimbra.
the class NativeFormatter method handleMessage.
private void handleMessage(UserServletContext context, Message msg) throws IOException, ServiceException, MessagingException, ServletException {
if (context.hasBody()) {
List<MPartInfo> parts = Mime.getParts(msg.getMimeMessage());
MPartInfo body = Mime.getTextBody(parts, false);
if (body != null) {
handleMessagePart(context, body.getMimePart(), msg);
} else {
context.resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "body not found");
}
} else if (context.hasPart()) {
MimePart mp = getMimePart(msg, context.getPart());
handleMessagePart(context, mp, msg);
} else {
context.resp.setContentType(MimeConstants.CT_TEXT_PLAIN);
long size = msg.getSize();
if (size > 0)
context.resp.setContentLength((int) size);
InputStream is = msg.getContentStream();
ByteUtil.copy(is, true, context.resp.getOutputStream(), false);
}
}
use of com.zimbra.cs.mime.MPartInfo in project zm-mailbox by Zimbra.
the class ToXML method addParts.
private static void addParts(Element root, MPartInfo mpiRoot, Set<MPartInfo> bodies, String prefix, int maxSize, boolean neuter, boolean excludeCalendarParts, String defaultCharset, boolean swallowContentExceptions, MsgContent wantContent) throws ServiceException {
MPartInfo mpi = mpiRoot;
LinkedList<Pair<Element, LinkedList<MPartInfo>>> queue = new LinkedList<Pair<Element, LinkedList<MPartInfo>>>();
Pair<Element, LinkedList<MPartInfo>> level = new Pair<Element, LinkedList<MPartInfo>>(root, new LinkedList<MPartInfo>());
level.getSecond().add(mpi);
queue.add(level);
VisitPhase phase = VisitPhase.PREVISIT;
while (!queue.isEmpty()) {
level = queue.getLast();
LinkedList<MPartInfo> parts = level.getSecond();
if (parts.isEmpty()) {
queue.removeLast();
phase = VisitPhase.POSTVISIT;
continue;
}
mpi = parts.getFirst();
Element child = addPart(phase, level.getFirst(), root, mpi, bodies, prefix, maxSize, neuter, excludeCalendarParts, defaultCharset, swallowContentExceptions, wantContent);
if (phase == VisitPhase.PREVISIT && child != null && mpi.hasChildren()) {
queue.addLast(new Pair<Element, LinkedList<MPartInfo>>(child, new LinkedList<MPartInfo>(mpi.getChildren())));
} else {
parts.removeFirst();
phase = VisitPhase.PREVISIT;
}
}
}
use of com.zimbra.cs.mime.MPartInfo in project zm-mailbox by Zimbra.
the class ToXML method encodeInvite.
public static Element encodeInvite(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem cal, Invite inv, boolean includeContent, boolean neuter) throws ServiceException {
Element ie = parent.addElement(MailConstants.E_INVITE);
setCalendarItemType(ie, cal.getType());
encodeTimeZoneMap(ie, cal.getTimeZoneMap());
//encodeAlarmTimes(ie, cal);
ie.addAttribute(MailConstants.A_CAL_SEQUENCE, inv.getSeqNo());
ie.addAttribute(MailConstants.A_ID, inv.getMailItemId());
ie.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, inv.getComponentNum());
if (inv.hasRecurId()) {
ie.addAttribute(MailConstants.A_CAL_RECURRENCE_ID, inv.getRecurId().toString());
}
encodeInviteComponent(ie, ifmt, octxt, cal, (ItemId) null, inv, NOTIFY_FIELDS, neuter);
if (includeContent && (inv.isPublic() || allowPrivateAccess(octxt, cal))) {
int invId = inv.getMailItemId();
MimeMessage mm = cal.getSubpartMessage(invId);
if (mm != null) {
List<MPartInfo> parts;
try {
parts = Mime.getParts(mm, getDefaultCharset(cal));
} catch (IOException ex) {
throw ServiceException.FAILURE(ex.getMessage(), ex);
} catch (MessagingException ex) {
throw ServiceException.FAILURE(ex.getMessage(), ex);
}
if (parts != null && !parts.isEmpty()) {
addParts(ie, parts.get(0), null, "", -1, false, true, getDefaultCharset(cal), true);
}
}
}
return ie;
}
Aggregations