use of javax.mail.internet.SharedInputStream in project zm-mailbox by Zimbra.
the class ParsedMessage method init.
/**
* Runs MIME mutators and converters, initializes {@link #mMimeMessage}, {@link #mExpandedMessage},
* {@link #mFileInputStream} and {@link #mReceivedDate} based on message content.
*/
private void init(Long receivedDate, boolean indexAttachments) throws MessagingException, IOException {
this.indexAttachments = indexAttachments;
if (mimeMessage == null) {
if (sharedStream == null) {
throw new IOException("Content stream has not been initialized.");
}
if (!(sharedStream instanceof SharedInputStream)) {
InputStream in = sharedStream;
sharedStream = null;
byte[] content = ByteUtil.getContent(in, 0);
sharedStream = new SharedByteArrayInputStream(content);
}
mimeMessage = expandedMessage = new Mime.FixedMimeMessage(JMSession.getSession(), sharedStream);
}
// Run mutators.
try {
runMimeMutators();
} catch (Exception e) {
wasMutated = false;
// Original stream has been read, so get a new one.
mimeMessage = expandedMessage = new Mime.FixedMimeMessage(JMSession.getSession(), getRawInputStream());
}
if (wasMutated()) {
// Original data is now invalid.
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
mimeMessage.writeTo(buffer);
byte[] content = buffer.toByteArray();
ByteUtil.closeStream(sharedStream);
sharedStream = new SharedByteArrayInputStream(content);
mimeMessage = expandedMessage = null;
mimeMessage = expandedMessage = new Mime.FixedMimeMessage(JMSession.getSession(), sharedStream);
}
ExpandMimeMessage expand = new ExpandMimeMessage(mimeMessage);
try {
expand.expand();
expandedMessage = expand.getExpanded();
} catch (Exception e) {
// roll back if necessary
expandedMessage = mimeMessage;
LOG.warn("exception while converting message; message will be analyzed unconverted", e);
}
// must set received-date before Lucene document is initialized
if (receivedDate == null) {
receivedDate = getZimbraDateHeader(mimeMessage);
}
setReceivedDate(receivedDate);
}
use of javax.mail.internet.SharedInputStream in project zm-mailbox by Zimbra.
the class ParsedContact method init.
private void init(Map<String, ? extends Object> fields, InputStream in) throws ServiceException {
if (fields == null) {
throw ServiceException.INVALID_REQUEST("contact must have fields", null);
}
// Initialized shared stream.
try {
if (in instanceof SharedInputStream) {
sharedStream = in;
} else if (in != null) {
byte[] content = ByteUtil.getContent(in, 1024);
sharedStream = new SharedByteArrayInputStream(content);
}
} catch (IOException e) {
throw MailServiceException.MESSAGE_PARSE_ERROR(e);
}
// Initialize fields.
Map<String, String> map = new HashMap<String, String>();
for (Map.Entry<String, ? extends Object> entry : fields.entrySet()) {
String key = StringUtil.stripControlCharacters(entry.getKey());
String value = null;
if (entry.getValue() instanceof String[]) {
// encode multi value attributes as JSONObject
try {
value = Contact.encodeMultiValueAttr((String[]) entry.getValue());
} catch (JSONException e) {
ZimbraLog.index.warn("Error encoding multi valued attribute " + key, e);
}
} else if (entry.getValue() instanceof String) {
value = StringUtil.stripControlCharacters((String) entry.getValue());
} else if (entry.getValue() instanceof ContactGroup) {
value = ((ContactGroup) entry.getValue()).encode();
}
if (key != null && !key.trim().isEmpty() && !Strings.isNullOrEmpty(value)) {
if (key.length() > ContactConstants.MAX_FIELD_NAME_LENGTH) {
throw ServiceException.INVALID_REQUEST("too big filed name", null);
} else if (value.length() > ContactConstants.MAX_FIELD_VALUE_LENGTH) {
throw MailServiceException.CONTACT_TOO_BIG(ContactConstants.MAX_FIELD_VALUE_LENGTH, value.length());
}
map.put(key, value);
}
}
if (map.isEmpty()) {
throw ServiceException.INVALID_REQUEST("contact must have fields", null);
} else if (map.size() > ContactConstants.MAX_FIELD_COUNT) {
throw ServiceException.INVALID_REQUEST("too many fields", null);
}
contactFields = map;
// Initialize attachments.
if (sharedStream != null) {
InputStream contentStream = null;
try {
// Parse attachments.
contentStream = getContentStream();
contactAttachments = parseBlob(contentStream);
for (Attachment attach : contactAttachments) {
contactFields.remove(attach.getName());
}
initializeSizeAndDigest();
} catch (MessagingException me) {
throw MailServiceException.MESSAGE_PARSE_ERROR(me);
} catch (IOException ioe) {
throw MailServiceException.MESSAGE_PARSE_ERROR(ioe);
} finally {
ByteUtil.closeStream(contentStream);
}
}
}
use of javax.mail.internet.SharedInputStream in project zm-mailbox by Zimbra.
the class TestBlobInputStream method runBlobInputStreamTest.
public void runBlobInputStreamTest() throws Exception {
String CONTENT = "0123456789";
createFile(CONTENT);
BlobInputStream in = new BlobInputStream(mFile, mFile.length());
// Test reading all content
String read = getContent(in, 100);
assertEquals(CONTENT, read);
checkEof(in);
in.close();
// Test reading beginning and end
in = new BlobInputStream(mFile, mFile.length());
assertEquals("01234", getContent(in, 5));
assertEquals("56789", getContent(in, 100));
checkEof(in);
in.close();
// Test invalid start/end
try {
in = new BlobInputStream(mFile, mFile.length(), 6L, 5L);
fail("Test with start=6 and end=5 should not have succeeded.");
} catch (IOException e) {
}
// Test skip
in = new BlobInputStream(mFile, mFile.length());
assertEquals(2, in.skip(2));
assertEquals("23", getContent(in, 2));
assertEquals(3, in.skip(3));
assertEquals("7", getContent(in, 1));
assertEquals(2, in.skip(1000));
checkEof(in);
in.close();
// Test mark
in = new BlobInputStream(mFile, mFile.length());
assertTrue(in.markSupported());
boolean success = true;
try {
in.reset();
} catch (IOException e) {
success = false;
}
assertFalse("reset() should not have succeeded", success);
assertEquals("012", getContent(in, 3));
in.mark(3);
assertEquals("34", getContent(in, 2));
in.reset();
assertEquals("34", getContent(in, 2));
assertEquals("56", getContent(in, 2));
success = true;
try {
in.reset();
} catch (IOException e) {
success = false;
}
assertFalse("reset() should not have succeeded", success);
in.close();
// Test reading a byte array with an offset.
in = new BlobInputStream(mFile, mFile.length());
byte[] buf = new byte[5];
for (int i = 0; i < 5; i++) {
buf[i] = 57;
}
int numRead = in.read(buf, 3, 2);
assertTrue("Unexpected number of bytes read: " + numRead, numRead == 1 || numRead == 2);
int[] untouchedIndexes = null;
if (numRead == 1) {
assertEquals((byte) '0', buf[3]);
untouchedIndexes = new int[] { 0, 1, 2, 4 };
}
if (numRead == 2) {
assertEquals((byte) '0', buf[3]);
assertEquals((byte) '1', buf[4]);
untouchedIndexes = new int[] { 0, 1, 2 };
}
for (int i : untouchedIndexes) {
assertEquals("Unexpected value at index " + i, 57, buf[i]);
}
in.close();
// Test reading into a byte array.
in = new BlobInputStream(mFile, mFile.length());
in.read();
in.read();
numRead = in.read(buf);
assertTrue(numRead > 0);
assertTrue(numRead <= 5);
byte[] test = new byte[numRead];
System.arraycopy(buf, 0, test, 0, numRead);
assertTrue("23456".startsWith(new String(test)));
in.close();
// Test substream - all content
InputStream sub = in.newStream(0, CONTENT.length());
assertEquals(CONTENT, getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream beginning
sub = in.newStream(0, 5);
assertEquals("01234", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream end
sub = in.newStream(5, 10);
assertEquals("56789", getContent(sub, 100));
checkEof(sub);
sub.close();
sub = in.newStream(5, -1);
assertEquals("56789", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream past EOF
assertEquals(null, in.newStream(5, 11));
// Test substream middle
sub = in.newStream(3, 6);
assertEquals("345", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream position
sub = in.newStream(3, 6);
assertEquals(0, ((SharedInputStream) sub).getPosition());
sub.read(new byte[2]);
assertEquals(2, ((SharedInputStream) sub).getPosition());
sub.close();
// Test sub-substream
InputStream subsub = ((BlobInputStream) sub).newStream(1, 3);
assertEquals("45", getContent(subsub, 100));
// Test position after reading 1 character
in.close();
in = new BlobInputStream(mFile, mFile.length());
assertEquals(0, in.getPosition());
in.read();
assertEquals(1, in.getPosition());
in.close();
// Test reading byte arrays until the end of the file
in = new BlobInputStream(mFile, mFile.length());
buf = new byte[4];
while ((numRead = in.read(buf)) >= 0) {
}
in.close();
mFile.delete();
}
use of javax.mail.internet.SharedInputStream in project zm-mailbox by Zimbra.
the class ZSharedFileInputStreamTest method bis.
@Test
public void bis() throws Exception {
final String CONTENT = "0123456789";
File file = createFile(CONTENT);
ZSharedFileInputStream in = new ZSharedFileInputStream(file);
// Test reading all content
String read = getContent(in, 100);
Assert.assertEquals(CONTENT, read);
checkEof(in);
in.close();
// Test reading beginning and end
in = new ZSharedFileInputStream(file);
Assert.assertEquals("01234", getContent(in, 5));
Assert.assertEquals("56789", getContent(in, 100));
checkEof(in);
in.close();
// Test invalid start/end
try {
in = new ZSharedFileInputStream(file, 6L, 5L);
Assert.fail("Test with start=6 and end=5 should not have succeeded.");
} catch (AssertionError e) {
}
// Test skip
in = new ZSharedFileInputStream(file);
Assert.assertEquals(2, in.skip(2));
Assert.assertEquals("23", getContent(in, 2));
Assert.assertEquals(3, in.skip(3));
Assert.assertEquals("7", getContent(in, 1));
Assert.assertEquals(2, in.skip(1000));
checkEof(in);
in.close();
// Test mark
in = new ZSharedFileInputStream(file);
Assert.assertTrue(in.markSupported());
try {
in.reset();
Assert.fail("reset() should not have succeeded");
} catch (IOException e) {
}
Assert.assertEquals("012", getContent(in, 3));
in.mark(3);
Assert.assertEquals("34", getContent(in, 2));
in.reset();
Assert.assertEquals("34", getContent(in, 2));
Assert.assertEquals("56", getContent(in, 2));
try {
in.reset();
} catch (IOException e) {
Assert.fail("reset() should not have succeeded");
}
in.close();
// Test reading a byte array with an offset.
in = new ZSharedFileInputStream(file);
byte[] buf = new byte[5];
for (int i = 0; i < 5; i++) {
buf[i] = 57;
}
int numRead = in.read(buf, 3, 2);
Assert.assertTrue("Unexpected number of bytes read: " + numRead, numRead == 1 || numRead == 2);
int[] untouchedIndexes = null;
if (numRead == 1) {
Assert.assertEquals((byte) '0', buf[3]);
untouchedIndexes = new int[] { 0, 1, 2, 4 };
} else if (numRead == 2) {
Assert.assertEquals((byte) '0', buf[3]);
Assert.assertEquals((byte) '1', buf[4]);
untouchedIndexes = new int[] { 0, 1, 2 };
}
for (int i : untouchedIndexes) {
Assert.assertEquals("Unexpected value at index " + i, 57, buf[i]);
}
in.close();
// Test reading into a byte array.
in = new ZSharedFileInputStream(file);
in.read();
in.read();
numRead = in.read(buf);
Assert.assertTrue(numRead > 0);
Assert.assertTrue(numRead <= 5);
byte[] test = new byte[numRead];
System.arraycopy(buf, 0, test, 0, numRead);
Assert.assertTrue("23456".startsWith(new String(test)));
in.close();
// Test substream - all content
InputStream sub = in.newStream(0, CONTENT.length());
Assert.assertEquals(CONTENT, getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream beginning
sub = in.newStream(0, 5);
Assert.assertEquals("01234", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream end
sub = in.newStream(5, 10);
Assert.assertEquals("56789", getContent(sub, 100));
checkEof(sub);
sub.close();
sub = in.newStream(5, -1);
Assert.assertEquals("56789", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream past EOF
sub = in.newStream(5, 11);
Assert.assertEquals("56789", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream middle
sub = in.newStream(3, 6);
Assert.assertEquals("345", getContent(sub, 100));
checkEof(sub);
sub.close();
// Test substream position
sub = in.newStream(3, 6);
Assert.assertEquals(0, ((SharedInputStream) sub).getPosition());
sub.read(new byte[2]);
Assert.assertEquals(2, ((SharedInputStream) sub).getPosition());
sub.close();
// Test sub-substream
InputStream subsub = ((ZSharedFileInputStream) sub).newStream(1, 3);
Assert.assertEquals("45", getContent(subsub, 100));
// Test position after reading 1 character
in.close();
in = new ZSharedFileInputStream(file);
Assert.assertEquals(0, in.getPosition());
in.read();
Assert.assertEquals(1, in.getPosition());
in.close();
// Test reading byte arrays until the end of the file
in = new ZSharedFileInputStream(file);
buf = new byte[4];
while ((numRead = in.read(buf)) >= 0) {
}
in.close();
file.delete();
}
use of javax.mail.internet.SharedInputStream in project zm-mailbox by Zimbra.
the class ZMimeParser method endPart.
/**
* Records the endpoint of a MIME part. Stores both the byte offset of
* the end of the part as well as the line count of the part body. If
* the part being ended was a multipart preamble and was of nonzero
* length, associates the part with its parent appropriately.
*/
private PartInfo endPart(long end, boolean clean, long lineStart) {
PartInfo pinfo = parts.remove(parts.size() - 1);
ZMimePart mp = pinfo.part;
if (pinfo.location == PartLocation.PREAMBLE) {
long bodyEnd = Math.max(pinfo.bodyStart, lineStart), length = lineStart - pinfo.bodyStart;
SharedInputStream bodyStream = (SharedInputStream) sis.newStream(pinfo.bodyStart, bodyEnd);
if (!clean && !parts.isEmpty()) {
PartInfo pcurrent = currentPart();
String enc = pcurrent.part.getEncoding();
if (enc != null && !ZMimeBodyPart.RAW_ENCODINGS.contains(enc)) {
// supposedly-encoded multipart and no boundary hit -- defer decoding and parsing
pcurrent.multi.setDataSource(new MimePartDataSource(pcurrent.part));
// don't save this as a preamble!
length = 0;
}
}
if (length > 0) {
try {
if (length > MAXIMUM_HEADER_LENGTH) {
// constrain preamble length to some reasonable value (64K)
bodyStream = (SharedInputStream) bodyStream.newStream(0, length = MAXIMUM_HEADER_LENGTH);
}
// save preamble to *parent* multipart
String preamble = new String(ByteUtil.readInput((InputStream) bodyStream, (int) length, (int) length), charset);
currentPart().multi.setPreamble(preamble);
} catch (IOException ioe) {
}
}
} else {
long bodyEnd = Math.max(pinfo.bodyStart, end), length = end - pinfo.bodyStart;
SharedInputStream bodyStream = (SharedInputStream) sis.newStream(pinfo.bodyStart, bodyEnd);
mp.endPart(bodyStream, length, lineNumber - pinfo.firstLine);
}
return currentPart();
}
Aggregations