use of com.helger.mail.datasource.ByteArrayDataSource in project as2-lib by phax.
the class MimeBodyPartFuncTest method testReadContentTransferEncodingBase64.
@Test
public void testReadContentTransferEncodingBase64() throws MessagingException, IOException {
final String sHTTP = "Content-Type: text/plain" + CHttp.EOL + "Content-Transfer-Encoding: base64" + CHttp.EOL + "x-custom: junit" + CHttp.EOL + "Content-Length: 44" + CHttp.EOL + CHttp.EOL + "VGVzdCBtZXNzYWdlCkxpbmUgMgoKTGluZSA0CkVPRg==" + CHttp.EOL;
InputStream aIS = new StringInputStream(sHTTP, StandardCharsets.ISO_8859_1);
// Parse all HTTP headers from stream
final InternetHeaders aHeaders = new InternetHeaders(aIS);
final String sCTE = aHeaders.getHeader(CHttpHeader.CONTENT_TRANSFER_ENCODING)[0];
if (StringHelper.hasText(sCTE))
aIS = AS2IOHelper.getContentTransferEncodingAwareInputStream(aIS, sCTE);
// Read the payload
final byte[] aData = StreamHelper.getAllBytes(aIS);
// Extract content type
final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aHeaders.getHeader(CHttpHeader.CONTENT_TYPE)[0]);
final MimeBodyPart aReceivedPart = new MimeBodyPart();
aReceivedPart.setDataHandler(new ByteArrayDataSource(aData, sReceivedContentType, null).getAsDataHandler());
aReceivedPart.setHeader("x-received", "true");
final NonBlockingByteArrayOutputStream aBAOS = new NonBlockingByteArrayOutputStream();
aReceivedPart.writeTo(aBAOS);
StreamHelper.close(aBAOS);
final String sMsgPart = aBAOS.getAsString(StandardCharsets.ISO_8859_1);
if (true)
LOGGER.info(sMsgPart);
}
use of com.helger.mail.datasource.ByteArrayDataSource in project as2-lib by phax.
the class HTTPHelper method readHttpRequest.
/**
* Read headers and payload from the passed input stream provider. For large
* file support, return {@link DataSource}. If is on, data is not read.
*
* @param aRDP
* The abstract input stream provider to use. May not be
* <code>null</code>.
* @param aResponseHandler
* The HTTP response handler to be used. May not be <code>null</code>.
* @param aMsg
* The Message to be filled. May not be <code>null</code>.
* @param aIncomingDumper
* Optional incoming HTTP dumper. May be <code>null</code>.
* @return A {@link IExtendedDataSource} that holds/refers to the body.
* @throws IOException
* In case of error reading from the InputStream
* @throws MessagingException
* In case header line parsing fails
*/
@Nonnull
public static IExtendedDataSource readHttpRequest(@Nonnull final IAS2HttpRequestDataProvider aRDP, @Nonnull final IAS2HttpResponseHandler aResponseHandler, @Nonnull final IMessage aMsg, @Nullable final IHTTPIncomingDumper aIncomingDumper) throws IOException, MessagingException {
// Request method (e.g. "POST")
aMsg.attrs().putIn(MA_HTTP_REQ_TYPE, aRDP.getHttpRequestMethod());
// Request URL (e.g. "/as2")
aMsg.attrs().putIn(MA_HTTP_REQ_URL, aRDP.getHttpRequestUrl());
// HTTP version (e.g. "HTTP/1.1")
aMsg.attrs().putIn(MA_HTTP_REQ_VERSION, aRDP.getHttpRequestVersion());
// Get the stream to read from
final InputStream aIS = aRDP.getHttpInputStream();
// Parse all HTTP headers from stream
aMsg.headers().setAllHeaders(aRDP.getHttpHeaderMap());
// Generate DataSource
// Put received data in a MIME body part
final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aMsg.getHeader(CHttpHeader.CONTENT_TYPE));
final byte[] aBytePayload;
final IExtendedDataSource aPayload;
final String sContentLength = aMsg.getHeader(CHttpHeader.CONTENT_LENGTH);
if (sContentLength == null) {
// No "Content-Length" header present
final InputStream aRealIS;
final String sTransferEncoding = aMsg.getHeader(CHttpHeader.TRANSFER_ENCODING);
if (sTransferEncoding != null) {
// Remove all whitespaces in the value
if (AS2Helper.getWithoutSpaces(sTransferEncoding).equalsIgnoreCase("chunked")) {
// chunked encoding. Use also file backed stream as the message
// might be large
@WillNotClose final TempSharedFileInputStream aSharedIS = TempSharedFileInputStream.getTempSharedFileInputStream(new ChunkedInputStream(aIS), aMsg.getMessageID());
aRealIS = aSharedIS;
aMsg.setTempSharedFileInputStream(aSharedIS);
} else {
// No "Content-Length" and unsupported "Transfer-Encoding"
sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_LENGTH_REQUIRED);
throw new IOException("Transfer-Encoding unimplemented: " + sTransferEncoding);
}
} else {
// No "Content-Length" and no "Transfer-Encoding"
sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_LENGTH_REQUIRED);
throw new IOException("Content-Length missing");
}
// Content-length present, or chunked encoding
aBytePayload = null;
aPayload = new InputStreamDataSource(aRealIS, aMsg.getAS2From() == null ? "" : aMsg.getAS2From(), sReceivedContentType, true);
} else {
// content-length exists
// Read the message body - no Content-Transfer-Encoding handling
// Retrieve the message content
// FIXME if a value > 2GB comes in, this will fail!!
final long nContentLength = StringParser.parseLong(sContentLength, -1);
if (nContentLength < 0 || nContentLength > Integer.MAX_VALUE) {
// Invalid content length (no int or too big)
sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_LENGTH_REQUIRED);
throw new IOException("Content-Length '" + sContentLength + "' is invalid. Only values between 0 and " + Integer.MAX_VALUE + " are allowed.");
}
aBytePayload = new byte[(int) nContentLength];
// Keeps the original InputStream open and that is okay
try (final DataInputStream aDataIS = new DataInputStream(aIS)) {
aDataIS.readFully(aBytePayload);
}
aPayload = new ByteArrayDataSource(aBytePayload, sReceivedContentType, null);
}
// Dump on demand
if (aIncomingDumper != null) {
aIncomingDumper.dumpIncomingRequest(getAllHTTPHeaderLines(aRDP.getHttpHeaderMap()), aBytePayload != null ? aBytePayload : "Payload body was not read yet, and therefore it cannot be dumped (yet) - sorry".getBytes(StandardCharsets.ISO_8859_1), aMsg);
}
return aPayload;
// Don't close the IS here!
}
use of com.helger.mail.datasource.ByteArrayDataSource in project as2-lib by phax.
the class HTTPHelper method readAndDecodeHttpRequest.
@Nonnull
public static DataSource readAndDecodeHttpRequest(@Nonnull final IAS2HttpRequestDataProvider aRDP, @Nonnull final IAS2HttpResponseHandler aResponseHandler, @Nonnull final IMessage aMsg, @Nullable final IHTTPIncomingDumper aIncomingDumper) throws IOException, MessagingException {
// Main read
DataSource aPayload = HTTPHelper.readHttpRequest(aRDP, aResponseHandler, aMsg, aIncomingDumper);
// Check the transfer encoding of the request. If none is provided, check
// the partnership for a default one. If none is in the partnership used the
// default one
final String sCTE = aMsg.partnership().getContentTransferEncodingReceive(EContentTransferEncoding.AS2_DEFAULT.getID());
final String sContentTransferEncoding = aMsg.getHeaderOrDefault(CHttpHeader.CONTENT_TRANSFER_ENCODING, sCTE);
if (StringHelper.hasText(sContentTransferEncoding)) {
final IContentTransferEncoding aCTE = EContentTransferEncoding.getFromIDCaseInsensitiveOrNull(sContentTransferEncoding);
if (aCTE == null) {
if (LOGGER.isWarnEnabled())
LOGGER.warn("Unsupported Content-Transfer-Encoding '" + sContentTransferEncoding + "' is used - ignoring!");
} else {
// Decode data if necessary
final IByteArrayCodec aCodec = aCTE.createCodec();
// TODO: Handle decoding when large file support is on
if (!(aCodec instanceof IdentityCodec<?>) && aPayload instanceof ByteArrayDataSource) {
byte[] aActualBytes = ((ByteArrayDataSource) aPayload).directGetBytes();
// Remember original length before continuing
final int nOriginalContentLength = aActualBytes.length;
if (LOGGER.isInfoEnabled())
LOGGER.info("Incoming message uses Content-Transfer-Encoding '" + sContentTransferEncoding + "' - decoding");
aActualBytes = aCodec.getDecoded(aActualBytes);
aPayload = new ByteArrayDataSource(aActualBytes, aPayload.getContentType(), aPayload.getName());
// Remember that we potentially did something
aMsg.attrs().putIn(MA_HTTP_ORIGINAL_CONTENT_TRANSFER_ENCODING, sContentTransferEncoding);
aMsg.attrs().putIn(MA_HTTP_ORIGINAL_CONTENT_LENGTH, nOriginalContentLength);
}
}
}
return aPayload;
}
Aggregations