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;
}
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);
}
}
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");
}
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;
}
}
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);
}
}
Aggregations