Repository navigation
[EMAIL-209] Return re-readable attachment data sources from MimeMessageParser - #403
Open
sharanggupta wants to merge 1 commit into
Open
sharanggupta wants to merge 1 commit into
sharanggupta wants to merge 1 commit into
Conversation
…geParser Since EMAIL-207, MimeMessageParser wrapped the one input stream of each attachment in an InputStreamDataSource, so a second getInputStream() call returned the consumed stream, contrary to the DataSource contract. Return a data source that opens a new stream of the part's content on each call instead, which still keeps no copy of the content. The part's stream is still opened once while parsing so that errors are reported by parse() as before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes EMAIL-209.
What
Since 1.6.0, the attachment data sources of
MimeMessageParsercan be read only once.createDataSource()opens the part's input stream when the message is parsed and wraps that one stream in anInputStreamDataSource, whosegetInputStream()returns it again on every call. A second read gets the stream where the first one stopped, so code that reads an attachment twice, as in the report, gets empty or truncated content. TheDataSourcecontract says that "a new InputStream object must be returned each time this method is called, and the stream must be positioned at the beginning of the data." In 1.5, the attachment was aByteArrayDataSource, which could be read any number of times, but it held a copy of every attachment in memory, which EMAIL-207 removed.How
createDataSource()now returns a small privateAttachmentDataSourcethat keeps the part's ownDataSource, with the base content type and the name as before. ItsgetInputStream()asks the part's data source for a new stream on each call; for a parsed message that is aMimePartDataSource, which decodes the content again each time. So every read starts at the beginning of the data, and the content is still not copied into memory, which keeps the fix for EMAIL-207. As withInputStreamDataSource,getOutputStream()throwsUnsupportedOperationException.createDataSource()still opens the part's stream once while parsing, and closes it right away, so that an exception from opening the part's content is still thrown byparse()as before, and not only when the attachment is read.The change is made in both the Jakarta and the javax modules.
InputStreamDataSourceitself is unchanged, since it is public API, but the parser no longer uses it.Two consequences worth knowing about:
FileDataSourceor aURLDataSourceattachment and parsed without serialising it, the file or URL is read again on each call, like these data sources do themselves.Tests
MimeMessageParserTestin both modules:testAttachmentCanBeReadTwicereads the 7bit text attachment ofmultipart-text-attachment.emltwice, and checks thatgetOutputStream()throwsUnsupportedOperationException.testBase64AttachmentCanBeReadTwicereads the base64 PDF attachment ofattachment-only.emltwice and compares the bytes.On master the second reads are empty:
expected: <test> but was: <>, andarray lengths differ, expected: <7555> but was: <0>. With this change both tests pass.testParseNoHeaderSeperatorWithOutOfMemoryfrom EMAIL-207 still passes.The default Maven goal (
clean verify apache-rat:check checkstyle:check pmd:check pmd:cpd-check spotbugs:check javadoc:javadoc) passes locally on Java 17.Before you push a pull request, review this list:
mvn; that'smvnon the command line by itself.