Search in sources :

Example 1 with TruncatingWriter

use of com.zimbra.common.util.TruncatingWriter in project zm-mailbox by Zimbra.

the class ToXML method addContent.

/** Adds the decoded text content of a message part to the {@link Element}.
     *  The content is added as the value of a new <tt>&lt;content></tt>
     *  sub-element.  <i>Note: This method will only extract the content of a
     *  <b>text/*</b> or <b>xml/*</b> message part.</i>
     *
     * @param elt     The element to add the <tt>&lt;content></tt> to.
     * @param mpi     The message part to extract the content from.
     * @param maxSize The maximum number of characters to inline (<=0 is unlimited).
     * @param neuter  Whether to "neuter" image <tt>src</tt> attributes.
     * @parame defaultCharset  The user's default charset preference.
     * @throws MessagingException when message parsing or CTE-decoding fails
     * @throws IOException on error during parsing or defanging
     * @see HtmlDefang#defang(String, boolean) */
private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset, MsgContent wantContent) throws IOException, MessagingException {
    // TODO: support other parts
    String ctype = mpi.getContentType();
    if (!ctype.matches(MimeConstants.CT_TEXT_WILD) && !ctype.matches(MimeConstants.CT_XML_WILD)) {
        return;
    }
    MimePart mp = mpi.getMimePart();
    Mime.repairTransferEncoding(mp);
    String data = null;
    String originalContent = null;
    wantContent = wantContent == null ? MsgContent.full : wantContent;
    try {
        if (maxSize <= 0) {
            maxSize = (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
        } else {
            maxSize = Math.min(maxSize, (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
        }
    } catch (ServiceException e) {
        ZimbraLog.soap.warn("Unable to determine max content size", e);
    }
    boolean wasTruncated = false;
    if (ctype.equals(MimeConstants.CT_TEXT_HTML)) {
        String charset = mpi.getContentTypeParameter(MimeConstants.P_CHARSET);
        InputStream stream = null;
        StringWriter sw = new StringWriter();
        TruncatingWriter tw = null;
        Writer out = sw;
        if (maxSize > 0) {
            tw = new TruncatingWriter(sw, maxSize + 1);
            out = tw;
        }
        Reader reader = null;
        try {
            stream = mp.getInputStream();
            if (charset != null && !charset.trim().isEmpty()) {
                // make sure to feed getTextReader() a full Content-Type header, not just the primary/subtype portion
                reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
                BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
                defanger.defang(reader, neuter, out);
                data = sw.toString();
            } else {
                String cte = mp.getEncoding();
                if (cte != null && !cte.trim().toLowerCase().equals(MimeConstants.ET_7BIT)) {
                    try {
                        DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
                        data = sw.toString();
                    } catch (IOException e) {
                    }
                }
                if (data == null) {
                    reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
                    DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
                    data = sw.toString();
                }
            }
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = removeQuotedText(data, true);
            }
        } finally {
            if (tw != null) {
                wasTruncated = tw.wasTruncated();
            }
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    } else if (ctype.equals(MimeConstants.CT_TEXT_ENRICHED)) {
        // Enriched text handling is a little funky because TextEnrichedHandler
        // doesn't use Reader and Writer.  As a result, we truncate
        // the source before converting to HTML.
        InputStream stream = mp.getInputStream();
        Reader reader = null;
        try {
            reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
            int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
            String enriched = ByteUtil.getContent(reader, maxChars, false);
            if (enriched.length() == maxChars) {
                // The normal check for truncated data won't work because
                // the length of the converted text is different than the length
                // of the source, so set the attr here.
                wasTruncated = true;
            }
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = TextEnrichedHandler.convertToHTML(removeQuotedText(enriched, false));
            }
            data = TextEnrichedHandler.convertToHTML(enriched);
        } finally {
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    } else {
        InputStream stream = mp.getInputStream();
        Reader reader = null;
        try {
            reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
            int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
            data = ByteUtil.getContent(reader, maxChars, false);
            if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
                originalContent = removeQuotedText(data, false);
            }
            if (data.length() == maxChars) {
                wasTruncated = true;
            }
        } finally {
            ByteUtil.closeStream(stream);
            Closeables.closeQuietly(reader);
        }
    }
    if (data != null && !wantContent.equals(MsgContent.original)) {
        data = StringUtil.stripControlCharacters(data);
        if (wasTruncated) {
            elt.addAttribute(MailConstants.A_TRUNCATED_CONTENT, true);
            if (data.length() > maxSize) {
                data = data.substring(0, maxSize);
            }
        }
        elt.addAttribute(MailConstants.E_CONTENT, data, Element.Disposition.CONTENT);
    }
    if (originalContent != null && (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both))) {
        originalContent = StringUtil.stripControlCharacters(originalContent);
        elt.addUniqueElement(MailConstants.E_ORIG_CONTENT).setText(originalContent);
    }
// TODO: CDATA worth the effort?
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) StringWriter(java.io.StringWriter) InputStream(java.io.InputStream) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) MimePart(javax.mail.internet.MimePart) Reader(java.io.Reader) BrowserDefang(com.zimbra.cs.html.BrowserDefang) IOException(java.io.IOException) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Example 2 with TruncatingWriter

use of com.zimbra.common.util.TruncatingWriter in project zm-mailbox by Zimbra.

the class TestUtilCode method doTruncatingWriterTest.

private void doTruncatingWriterTest(int maxChars) throws Exception {
    String original = "Come talk to me";
    StringWriter sw = new StringWriter();
    Writer w = new TruncatingWriter(sw, maxChars);
    w.append(original);
    String s = sw.toString();
    int actualChars = Math.min(maxChars, original.length());
    assertEquals(actualChars, s.length());
    assertEquals(original.substring(0, actualChars), s);
}
Also used : StringWriter(java.io.StringWriter) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) TruncatingWriter(com.zimbra.common.util.TruncatingWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Aggregations

TruncatingWriter (com.zimbra.common.util.TruncatingWriter)2 StringWriter (java.io.StringWriter)2 Writer (java.io.Writer)2 ServiceException (com.zimbra.common.service.ServiceException)1 BrowserDefang (com.zimbra.cs.html.BrowserDefang)1 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Reader (java.io.Reader)1 MimePart (javax.mail.internet.MimePart)1