use of com.helger.mail.datasource.InputStreamDataSource 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!
}
Aggregations