Search in sources :

Example 1 with InputStreamWithSize

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

the class ImapPartSpecifier method getContentOctetRangeFromFullContents.

private InputStreamWithSize getContentOctetRangeFromFullContents(InputStreamWithSize contents) throws IOException, BinaryDecodingException, ServiceException {
    if (octetStart >= 0 && contents != null) {
        // if there is a "partial" octet start/length constraint on this
        // part specifier, apply it here
        InputStream is = contents.stream;
        long statedLength = contents.size;
        long realLength = Math.max(0, Math.min(statedLength < 0 ? Integer.MAX_VALUE : statedLength, octetEnd) - octetStart);
        try {
            int start = octetStart;
            // don't do skip() correctly
            if (is instanceof com.sun.mail.util.BASE64DecoderStream || is instanceof com.sun.mail.util.QPDecoderStream) {
                ByteUtil.skip(is, start);
                start = 0;
            }
            is = ByteUtil.SegmentInputStream.create(is, start, start + realLength);
        } catch (StartOutOfBoundsException e) {
            // return empty string {0} when start is out of range
            ZimbraLog.imap.warn("IMAP part requested start out of range", e);
            is = new ByteArrayInputStream(new byte[0]);
            statedLength = realLength = 0;
        } catch (IOException ioe) {
            ByteUtil.closeStream(is);
            throw ioe;
        }
        contents = new InputStreamWithSize(is, statedLength < 0 ? -1 : realLength);
    }
    return contents;
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) StartOutOfBoundsException(com.zimbra.common.util.StartOutOfBoundsException) InputStreamWithSize(com.zimbra.common.util.InputStreamWithSize) IOException(java.io.IOException)

Example 2 with InputStreamWithSize

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

the class RemoteImapMailboxStore method getByImapId.

@Override
public InputStreamWithSize getByImapId(OperationContext octxt, int imapId, String folderId, String resolvedPath) throws ServiceException {
    AuthToken auth;
    try {
        auth = AuthToken.getAuthToken(zMailbox.getAuthToken().getValue());
    } catch (AuthTokenException ate) {
        ZimbraLog.imap.error("Problem with auth token", ate);
        throw ServiceException.AUTH_EXPIRED("Problem creating auth token for use with UserServlet");
    }
    HashMap<String, String> params = Maps.newHashMapWithExpectedSize(1);
    params.put(UserServlet.QP_IMAP_ID, Integer.toString(imapId));
    UserServlet.HttpInputStream is;
    try {
        is = UserServlet.getRemoteContentAsStream(auth, getAccount(), resolvedPath, params);
        return new InputStreamWithSize(is, (long) is.getContentLength());
    } catch (IOException e) {
        throw ServiceException.FAILURE(String.format("Failed to get content stream for item id %d", imapId), e);
    }
}
Also used : UserServlet(com.zimbra.cs.service.UserServlet) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) InputStreamWithSize(com.zimbra.common.util.InputStreamWithSize) IOException(java.io.IOException)

Example 3 with InputStreamWithSize

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

the class ImapURL method getContentAsStream.

public InputStreamWithSize getContentAsStream(ImapHandler handler, ImapCredentials creds, String tag) throws ImapException {
    ImapHandler.State state = handler.getState();
    if (state == ImapHandler.State.NOT_AUTHENTICATED) {
        throw new ImapUrlException(tag, mURL, "must be in AUTHENTICATED state");
    }
    try {
        Account acct = Provisioning.getInstance().get(AccountBy.name, mUsername);
        if (acct == null) {
            throw new ImapUrlException(tag, mURL, "cannot find user: " + mUsername);
        }
        ImapListener i4session = handler.getCurrentImapListener();
        OperationContext octxt = creds.getContext().setSession(i4session);
        InputStreamWithSize content = null;
        // special-case the situation where the relevant folder is already SELECTed
        ImapFolder i4folder = handler.getSelectedFolder();
        if (state == ImapHandler.State.SELECTED && (i4session != null) && (i4folder != null) && acct.getId().equals(i4session.getTargetAccountId()) && mPath.isEquivalent(i4folder.getPath())) {
            ImapMessage i4msg = i4folder.getByImapId(mUid);
            if (i4msg == null || i4msg.isExpunged()) {
                throw new ImapUrlException(tag, mURL, "no such message");
            }
            MailboxStore i4Mailbox = i4folder.getMailbox();
            ZimbraMailItem item = i4Mailbox.getItemById(octxt, ItemIdentifier.fromAccountIdAndItemId(i4Mailbox.getAccountId(), i4msg.msgId), i4msg.getMailItemType());
            content = ImapMessage.getContent(item);
        }
        // if not, have to fetch by IMAP UID if we're local or handle off-server URLs
        if (content == null) {
            ImapMailboxStore mbox = mPath.getOwnerImapMailboxStore();
            content = mbox.getByImapId(octxt, mUid, mPath.getFolder().getFolderIdAsString(), mPath.asResolvedPath());
            if (null == content) {
                throw new ImapUrlException(tag, mURL, "no such message");
            }
        }
        // fetch the content of the message
        if (mPart == null) {
            return content;
        }
        // and return the appropriate subpart of the selected message
        MimeMessage mm;
        try {
            mm = new Mime.FixedMimeMessage(JMSession.getSession(), content.stream);
        } finally {
            content.stream.close();
        }
        InputStreamWithSize part = mPart.getContentOctetRange(mm);
        if (part == null) {
            throw new ImapUrlException(tag, mURL, "no such part");
        }
        return part;
    } catch (NoSuchItemException e) {
        ZimbraLog.imap.info("no such message", e);
    } catch (ServiceException | MessagingException | BinaryDecodingException e) {
        ZimbraLog.imap.info("can't fetch content from IMAP URL", e);
    } catch (IOException e) {
        ZimbraLog.imap.info("error reading content from IMAP URL", e);
    }
    throw new ImapUrlException(tag, mURL, "error fetching IMAP URL content");
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Account(com.zimbra.cs.account.Account) MailboxStore(com.zimbra.common.mailbox.MailboxStore) MessagingException(javax.mail.MessagingException) IOException(java.io.IOException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) Mime(com.zimbra.cs.mime.Mime) BinaryDecodingException(com.zimbra.cs.imap.ImapPartSpecifier.BinaryDecodingException) ServiceException(com.zimbra.common.service.ServiceException) MimeMessage(javax.mail.internet.MimeMessage) InputStreamWithSize(com.zimbra.common.util.InputStreamWithSize) ZimbraMailItem(com.zimbra.common.mailbox.ZimbraMailItem)

Example 4 with InputStreamWithSize

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

the class ImapPartSpecifier method getContent.

private InputStreamWithSize getContent(MimeMessage msg) throws BinaryDecodingException {
    long length = -1;
    InputStream is = null;
    try {
        MimePart mp = Mime.getMimePart(msg, part);
        if (mp == null) {
            return null;
        }
        // TEXT and HEADER* modifiers operate on rfc822 messages
        if ((modifier.equals("TEXT") || modifier.startsWith("HEADER")) && !(mp instanceof MimeMessage)) {
            // FIXME: hackaround for JavaMail's failure to handle multipart/digest properly
            Object content = Mime.getMessageContent(mp);
            if (!(content instanceof MimeMessage)) {
                return null;
            }
            mp = (MimeMessage) content;
        }
        // get the content of the requested part
        if (modifier.equals("")) {
            if (mp instanceof MimeBodyPart) {
                if (command.startsWith("BINARY")) {
                    try {
                        is = ((MimeBodyPart) mp).getInputStream();
                    } catch (IOException ioe) {
                        throw new BinaryDecodingException();
                    }
                } else {
                    is = ((MimeBodyPart) mp).getRawInputStream();
                    length = Math.max(0, mp.getSize());
                }
            } else if (mp instanceof MimeMessage) {
                if (!isMessageBody(msg, mp)) {
                    String parentPart = part.substring(0, Math.max(0, part.length() - 2));
                    return new ImapPartSpecifier(command, parentPart, "TEXT").getContent(msg);
                } else if (command.startsWith("BINARY")) {
                    try {
                        is = ((MimeMessage) mp).getInputStream();
                    } catch (IOException ioe) {
                        throw new BinaryDecodingException();
                    }
                } else {
                    is = ((MimeMessage) mp).getRawInputStream();
                    length = Math.max(0, mp.getSize());
                }
            } else {
                ZimbraLog.imap.debug("getting content of part; not MimeBodyPart: " + this);
                return ImapMessage.EMPTY_CONTENT;
            }
        } else if (modifier.startsWith("HEADER")) {
            MimeMessage mm = (MimeMessage) mp;
            Enumeration<?> headers;
            if (modifier.equals("HEADER")) {
                headers = mm.getAllHeaderLines();
            } else if (modifier.equals("HEADER.FIELDS")) {
                headers = mm.getMatchingHeaderLines(getHeaders());
            } else {
                headers = mm.getNonMatchingHeaderLines(getHeaders());
            }
            StringBuilder result = new StringBuilder();
            while (headers.hasMoreElements()) {
                result.append(headers.nextElement()).append(ImapHandler.LINE_SEPARATOR);
            }
            byte[] content = result.append(ImapHandler.LINE_SEPARATOR).toString().getBytes();
            is = new ByteArrayInputStream(content);
            length = content.length;
        } else if (modifier.equals("MIME")) {
            if (mp instanceof MimeMessage) {
                String parentPart = part.substring(0, Math.max(0, part.length() - 2));
                return new ImapPartSpecifier(command, parentPart, "HEADER").getContent(msg);
            }
            Enumeration<?> mime = mp.getAllHeaderLines();
            StringBuilder result = new StringBuilder();
            while (mime.hasMoreElements()) {
                result.append(mime.nextElement()).append(ImapHandler.LINE_SEPARATOR);
            }
            byte[] content = result.append(ImapHandler.LINE_SEPARATOR).toString().getBytes();
            is = new ByteArrayInputStream(content);
            length = content.length;
        } else if (modifier.equals("TEXT")) {
            is = ((MimeMessage) mp).getRawInputStream();
            length = Math.max(0, mp.getSize());
        } else {
            return null;
        }
        return new InputStreamWithSize(is, length);
    } catch (IOException e) {
        ByteUtil.closeStream(is);
        return null;
    } catch (MessagingException e) {
        ByteUtil.closeStream(is);
        return null;
    }
}
Also used : Enumeration(java.util.Enumeration) MessagingException(javax.mail.MessagingException) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) MimeMessage(javax.mail.internet.MimeMessage) ByteArrayInputStream(java.io.ByteArrayInputStream) MimePart(javax.mail.internet.MimePart) InputStreamWithSize(com.zimbra.common.util.InputStreamWithSize) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 5 with InputStreamWithSize

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

the class ImapPartSpecifier method write.

private void write(PrintStream ps, OutputStream os, GettableInputStreamWithSize gisws) throws IOException, BinaryDecodingException, ServiceException {
    InputStream is = null;
    try {
        InputStreamWithSize contents = getContentOctetRange(gisws);
        is = contents == null ? null : contents.stream;
        long length = contents == null ? -1 : contents.size;
        ps.print(this);
        ps.write(' ');
        if (is == null) {
            ps.print("NIL");
        } else if (command.equals("BINARY.SIZE")) {
            ps.print(length >= 0 ? length : NULCheck.getLength(is));
        } else {
            boolean binary = false;
            if (command.startsWith("BINARY")) {
                NULCheck nul = NULCheck.hasNULs(is, length);
                if (length < 0) {
                    length = nul.length;
                }
                if (nul.content == null) {
                    // reload the original InputStream
                    is = getContentOctetRange(gisws).stream;
                } else {
                    // use the cached copy
                    is = new ByteArrayInputStream(nul.content);
                }
                binary = nul.hasNULs;
            }
            ps.print(binary ? "~{" : "{");
            ps.print(length);
            ps.write('}');
            /* } added to fix vim buggy brace matching code */
            if (os != null) {
                os.write(ImapHandler.LINE_SEPARATOR_BYTES);
                long written = ByteUtil.copy(is, false, os, false);
                assert written == length;
            }
        }
    } finally {
        ByteUtil.closeStream(is);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) InputStreamWithSize(com.zimbra.common.util.InputStreamWithSize)

Aggregations

InputStreamWithSize (com.zimbra.common.util.InputStreamWithSize)6 IOException (java.io.IOException)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 InputStream (java.io.InputStream)3 MessagingException (javax.mail.MessagingException)2 MimeMessage (javax.mail.internet.MimeMessage)2 MailboxStore (com.zimbra.common.mailbox.MailboxStore)1 ZimbraMailItem (com.zimbra.common.mailbox.ZimbraMailItem)1 ServiceException (com.zimbra.common.service.ServiceException)1 StartOutOfBoundsException (com.zimbra.common.util.StartOutOfBoundsException)1 Account (com.zimbra.cs.account.Account)1 AuthToken (com.zimbra.cs.account.AuthToken)1 AuthTokenException (com.zimbra.cs.account.AuthTokenException)1 BinaryDecodingException (com.zimbra.cs.imap.ImapPartSpecifier.BinaryDecodingException)1 NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)1 OperationContext (com.zimbra.cs.mailbox.OperationContext)1 Mime (com.zimbra.cs.mime.Mime)1 UserServlet (com.zimbra.cs.service.UserServlet)1 Enumeration (java.util.Enumeration)1 MimeBodyPart (javax.mail.internet.MimeBodyPart)1