use of com.helger.as2lib.util.AS2ResourceHelper in project as2-lib by phax.
the class AS2MDNReceiverHandler method handleIncomingMessage.
public void handleIncomingMessage(@Nonnull @Nonempty final String sClientInfo, @Nonnull final DataSource aMsgData, @Nonnull final AS2Message aMsg, @Nonnull final IAS2HttpResponseHandler aResponseHandler) {
// Read in the message request, headers, and data
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
final byte[] aData = StreamHelper.getAllBytes(aMsgData.getInputStream());
// Asynch MDN 2007-03-12
// check if the requested URL is defined in attribute "as2_receipt_option"
// in one of partnerships, if yes, then process incoming AsyncMDN
final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aMsg.getHeader(CHttpHeader.CONTENT_TYPE));
final MimeBodyPart aReceivedPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMsg.headers()), aData);
aMsg.setData(aReceivedPart);
// MimeBodyPart receivedPart = new MimeBodyPart();
aReceivedPart.setDataHandler(new ByteArrayDataSource(aData, sReceivedContentType, null).getAsDataHandler());
// Must be set AFTER the DataHandler!
aReceivedPart.setHeader(CHttpHeader.CONTENT_TYPE, sReceivedContentType);
aMsg.setData(aReceivedPart);
receiveMDN(aMsg, aData, aResponseHandler, aResHelper);
if (LOGGER.isInfoEnabled())
LOGGER.info("Received async MDN " + sClientInfo + aMsg.getLoggingText());
} catch (final Exception ex) {
m_aReceiverModule.handleError(aMsg, WrappedAS2Exception.wrap(ex));
}
}
use of com.helger.as2lib.util.AS2ResourceHelper in project as2-lib by phax.
the class AS2ReceiverHandler method handleIncomingMessage.
/**
* This method can be used to handle an incoming HTTP message AFTER the
* headers where extracted.
*
* @param sClientInfo
* Client connection info
* @param aMsgData
* The message body
* @param aMsg
* The AS2 message that will be filled by this method
* @param aResponseHandler
* The response handler which handles HTTP error messages as well as
* synchronous MDN.
*/
public void handleIncomingMessage(@Nonnull final String sClientInfo, @Nonnull final DataSource aMsgData, @Nonnull final AS2Message aMsg, @Nonnull final IAS2HttpResponseHandler aResponseHandler) {
// handler, to avoid the decrypted content gets removed (see issue #135)
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
try {
final IAS2Session aSession = m_aReceiverModule.getSession();
try {
// Put received data in a MIME body part
final String sReceivedContentType = AS2HttpHelper.getCleanContentType(aMsg.getHeader(CHttpHeader.CONTENT_TYPE));
final MimeBodyPart aReceivedPart = new MimeBodyPart();
aReceivedPart.setDataHandler(new DataHandler(aMsgData));
// Header must be set AFTER the DataHandler!
aReceivedPart.setHeader(CHttpHeader.CONTENT_TYPE, sReceivedContentType);
aMsg.setData(aReceivedPart);
} catch (final Exception ex) {
throw new AS2DispositionException(DispositionType.createError("unexpected-processing-error"), AbstractActiveNetModule.DISP_PARSING_MIME_FAILED, ex);
}
// update the message
try {
final String sAS2From = aMsg.getAS2From();
aMsg.partnership().setSenderAS2ID(sAS2From);
final String sAS2To = aMsg.getAS2To();
aMsg.partnership().setReceiverAS2ID(sAS2To);
// Fill all partnership attributes etc.
aSession.getPartnershipFactory().updatePartnership(aMsg, false);
} catch (final AS2Exception ex) {
throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("authentication-failed"), () -> AbstractActiveNetModule.DISP_PARTNERSHIP_NOT_FOUND);
}
// Per RFC5402 compression is always before encryption but can be before
// or after signing of message but only in one place
final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();
boolean bIsDecompressed = false;
// Decrypt and verify signature of the data, and attach data to the
// message
decrypt(aMsg, aResHelper);
if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
if (LOGGER.isTraceEnabled())
LOGGER.trace("Decompressing received message before checking signature...");
decompress(aMsg);
bIsDecompressed = true;
}
verify(aMsg, aResHelper);
if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
// or after signing of message but only in one place
if (bIsDecompressed) {
throw new AS2DispositionException(DispositionType.createError("decompression-failed"), AbstractActiveNetModule.DISP_DECOMPRESSION_ERROR, new Exception("Message has already been decompressed. Per RFC5402 it cannot occur twice."));
}
if (LOGGER.isTraceEnabled())
if (aMsg.attrs().containsKey(AS2Message.ATTRIBUTE_RECEIVED_SIGNED))
LOGGER.trace("Decompressing received message after verifying signature...");
else
LOGGER.trace("Decompressing received message after decryption...");
decompress(aMsg);
bIsDecompressed = true;
}
if (LOGGER.isTraceEnabled())
try {
LOGGER.trace("SMIME Decrypted Content-Disposition: " + aMsg.getContentDisposition() + "\n Content-Type received: " + aMsg.getContentType() + "\n HEADERS after decryption: " + aMsg.getData().getAllHeaders() + "\n Content-Disposition in MSG detData() MIMEPART after decryption: " + aMsg.getData().getContentType());
} catch (final MessagingException ex) {
if (LOGGER.isErrorEnabled())
LOGGER.error("Failed to trace message: " + aMsg, ex);
}
// Validate the received message before storing
try {
aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_VALIDATE_BEFORE_STORE, aMsg, null);
} catch (final AS2NoModuleException ex) {
// No module installed - ignore
} catch (final AS2Exception ex) {
// Issue 90 - use CRLF as separator
throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_VALIDATION_FAILED, CHttp.EOL, _getDispositionText(ex)));
}
// Store the received message
try {
aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STORE, aMsg, null);
} catch (final AS2NoModuleException ex) {
// No module installed - ignore
} catch (final AS2Exception ex) {
// Issue 90 - use CRLF as separator
throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_STORAGE_FAILED, CHttp.EOL, _getDispositionText(ex)));
}
// Validate the received message after storing
try {
aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_VALIDATE_AFTER_STORE, aMsg, null);
} catch (final AS2NoModuleException ex) {
// No module installed - ignore
} catch (final AS2Exception ex) {
// Issue 90 - use CRLF as separator
throw AS2DispositionException.wrap(ex, () -> DispositionType.createError("unexpected-processing-error"), () -> StringHelper.getConcatenatedOnDemand(AbstractActiveNetModule.DISP_VALIDATION_FAILED, CHttp.EOL, _getDispositionText(ex)));
}
try {
if (aMsg.isRequestingMDN()) {
if (LOGGER.isTraceEnabled())
LOGGER.trace("AS2 message is requesting an MDN");
// Transmit a success MDN if requested
sendMDN(sClientInfo, aResponseHandler, aMsg, DispositionType.createSuccess(), AbstractActiveNetModule.DISP_SUCCESS, ESuccess.SUCCESS);
} else {
if (LOGGER.isTraceEnabled())
LOGGER.trace("AS2 message is not requesting an MDN - just sending HTTP 200 (OK)");
// Just send a HTTP OK
HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, CHttp.HTTP_OK);
if (LOGGER.isInfoEnabled())
LOGGER.info("sent HTTP OK " + sClientInfo + aMsg.getLoggingText());
}
} catch (final Exception ex) {
throw new AS2Exception("Error creating and returning MDN, message was stilled processed", ex);
}
} catch (final AS2DispositionException ex) {
sendMDN(sClientInfo, aResponseHandler, aMsg, ex.getDisposition(), ex.getText(), ESuccess.FAILURE);
m_aReceiverModule.handleError(aMsg, ex);
} catch (final AS2Exception ex) {
m_aReceiverModule.handleError(aMsg, ex);
} finally {
// close the temporary shared stream if it exists
final TempSharedFileInputStream sis = aMsg.getTempSharedFileInputStream();
if (null != sis) {
try {
sis.closeAll();
} catch (final IOException e) {
LOGGER.error("Exception while closing TempSharedFileInputStream", e);
}
}
}
}
}
use of com.helger.as2lib.util.AS2ResourceHelper in project as2-lib by phax.
the class AS2SenderModule method handle.
public void handle(@Nonnull final String sAction, @Nonnull final IMessage aBaseMsg, @Nullable final Map<String, Object> aOptions) throws AS2Exception {
final AS2Message aMsg = (AS2Message) aBaseMsg;
if (LOGGER.isInfoEnabled())
LOGGER.info("Submitting message" + aMsg.getLoggingText());
// verify all required information is present for sending
checkRequired(aMsg);
final int nRetries = getRetryCount(aMsg.partnership(), aOptions);
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
// Get Content-Transfer-Encoding to use
final String sContentTransferEncoding = aMsg.partnership().getContentTransferEncodingSend(EContentTransferEncoding.AS2_DEFAULT.getID());
final EContentTransferEncoding eCTE = EContentTransferEncoding.getFromIDCaseInsensitiveOrDefault(sContentTransferEncoding, EContentTransferEncoding.AS2_DEFAULT);
// compress and/or sign and/or encrypt the message if needed
final MimeBodyPart aSecuredData = secure(aMsg, eCTE);
// Calculate MIC after compress/sign/crypt was handled, because the
// message data might change if compression before signing is active.
final MIC aMIC;
if (aMsg.isRequestingMDN())
aMIC = calculateAndStoreMIC(aMsg);
else
aMIC = null;
if (LOGGER.isDebugEnabled())
LOGGER.debug("Setting message content type to '" + aSecuredData.getContentType() + "'");
aMsg.setContentType(aSecuredData.getContentType());
try (final IHTTPOutgoingDumper aOutgoingDumper = getHttpOutgoingDumper(aMsg)) {
final IHTTPIncomingDumper aIncomingDumper = getEffectiveHttpIncomingDumper();
// Use no CTE, because it was set on all MIME parts
_sendViaHTTP(aMsg, aSecuredData, aMIC, true ? null : eCTE, aOutgoingDumper, aIncomingDumper, aResHelper);
}
} catch (final AS2HttpResponseException ex) {
if (LOGGER.isErrorEnabled())
LOGGER.error("Http Response Error " + ex.getMessage());
ex.terminate(aMsg);
if (!doResend(IProcessorSenderModule.DO_SEND, aMsg, ex, nRetries))
throw ex;
} catch (final IOException ex) {
// Re-send if a network error occurs during transmission
final AS2Exception wioe = WrappedAS2Exception.wrap(ex).setSourceMsg(aMsg).terminate();
if (!doResend(IProcessorSenderModule.DO_SEND, aMsg, wioe, nRetries))
throw wioe;
} catch (final Exception ex) {
// Propagate error if it can't be handled by a re-send
throw WrappedAS2Exception.wrap(ex);
}
}
use of com.helger.as2lib.util.AS2ResourceHelper in project as2-lib by phax.
the class AsynchMDNSenderModule method handle.
public void handle(@Nonnull final String sAction, @Nonnull final IMessage aBaseMsg, @Nullable final Map<String, Object> aOptions) throws AS2Exception {
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
final AS2Message aMsg = (AS2Message) aBaseMsg;
if (LOGGER.isInfoEnabled())
LOGGER.info("Async MDN submitted" + aMsg.getLoggingText());
final DispositionType aDisposition = DispositionType.createSuccess();
final int nRetries = getRetryCount(aMsg.partnership(), aOptions);
try (final IHTTPOutgoingDumper aOutgoingDumper = getHttpOutgoingDumper(aMsg)) {
_sendViaHTTP(aMsg, aDisposition, aOutgoingDumper, aResHelper);
} catch (final AS2HttpResponseException ex) {
if (LOGGER.isErrorEnabled())
LOGGER.error("Http Response Error " + ex.getMessage());
// Resend if the HTTP Response has an error code
ex.terminate();
if (!doResend(IProcessorSenderModule.DO_SEND_ASYNC_MDN, aMsg, ex, nRetries))
throw ex;
} catch (final IOException ex) {
// Resend if a network error occurs during transmission
final AS2Exception wioe = WrappedAS2Exception.wrap(ex).setSourceMsg(aMsg).terminate();
if (!doResend(IProcessorSenderModule.DO_SEND_ASYNC_MDN, aMsg, wioe, nRetries))
throw wioe;
} catch (final Exception ex) {
// Propagate error if it can't be handled by a resend
throw WrappedAS2Exception.wrap(ex);
}
} finally {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Async MDN message sent");
}
}
use of com.helger.as2lib.util.AS2ResourceHelper in project as2-lib by phax.
the class ReadMDNFuncTest method testReadMDNIssue97.
@Test
@Ignore("Part does not contain MimeMultipart")
public void testReadMDNIssue97() throws Exception {
final String sPrefix = "mdn/issue97";
final IReadableResource aHeaderRes = new ClassPathResource(sPrefix + ".header");
assertTrue(aHeaderRes.exists());
final IReadableResource aPayloadRes = new ClassPathResource(sPrefix + ".payload");
assertTrue(aPayloadRes.exists());
if (false) {
final IReadableResource aCertRes = new ClassPathResource(sPrefix + ".pem");
assertTrue(aCertRes.exists());
}
final HttpHeaderMap aHeaders = new HttpHeaderMap();
try (NonBlockingBufferedReader aBR = new NonBlockingBufferedReader(aHeaderRes.getReader(StandardCharsets.ISO_8859_1))) {
String s;
while ((s = aBR.readLine()) != null) {
final int i = s.indexOf(':');
final String sName = s.substring(0, i).trim();
final String sValue = s.substring(i + 1).trim();
aHeaders.addHeader(sName, sValue);
}
}
if (false)
assertEquals("<MOKOsi42435716cf621589dnode1POP000046@sfgt1.unix.fina.hr>", aHeaders.getFirstHeaderValue("Message-ID"));
// final X509Certificate aCert =
// CertificateHelper.convertStringToCertficateOrNull
// (StreamHelper.getAllBytesAsString (aCertRes,
// StandardCharsets.ISO_8859_1));
// assertNotNull (aCert);
final AS2Message aMsg = new AS2Message();
// Create a MessageMDN and copy HTTP headers
final IMessageMDN aMDN = new AS2MessageMDN(aMsg);
aMDN.headers().addAllHeaders(aHeaders);
final MimeBodyPart aPart = new MimeBodyPart(AS2HttpHelper.getAsInternetHeaders(aMDN.headers()), StreamHelper.getAllBytes(aPayloadRes));
assertNotNull(aPart);
aMsg.getMDN().setData(aPart);
final ICryptoHelper aCryptoHelper = AS2Helper.getCryptoHelper();
assertTrue(aCryptoHelper.isSigned(aPart));
assertFalse(aCryptoHelper.isEncrypted(aPart));
assertFalse(aCryptoHelper.isCompressed(aPart.getContentType()));
try (final AS2ResourceHelper aResHelper = new AS2ResourceHelper()) {
final Consumer<X509Certificate> aCertHolder = null;
AS2Helper.parseMDN(aMsg, null, true, aCertHolder, aResHelper);
}
}
Aggregations