public AlfrescoMimeMultipart(String subtype, FileInfo messageFileInfo) {
   super();
   String boundary = getBoundaryValue(messageFileInfo);
   ContentType cType = new ContentType("multipart", subtype, null);
   cType.setParameter("boundary", boundary);
   contentType = cType.toString();
 }
Beispiel #2
0
  public static String getText(Part part) {

    try {
      ContentType contentType = new ContentType(part.getContentType());
      System.err.println(
          "contentType: "
              + part.getContentType()
              + ", class: "
              + part.getContent().getClass().getName());

      if (part.isMimeType("text/*")) {
        String charset = contentType.getParameter("charset");
        System.err.println("Charset: " + charset);

        return (String) part.getContent();

      } else if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        for (int i = 0; i < mp.getCount(); i++) {
          String text = getText(mp.getBodyPart(i));

          if (text != null) {
            return text;
          }
        }
      }
      return null;
    } catch (ParseException e) {
      throw new RuntimeException(e);
    } catch (MessagingException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see javax.servlet.http.HttpServlet#service(javax.servlet.ServletRequest,
   * javax.servlet.ServletResponse)
   */
  @Override
  public void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    try {
      String messageId = request.getParameter("messageId");
      String attachmentIndex = request.getParameter("attachmentIndex");
      boolean isThumbnail = Boolean.valueOf(request.getParameter("thumbnail")).booleanValue();

      if (messageId != null) {
        IMailbox mailbox = SessionManager.get().getMailbox();
        Message msg = mailbox.getCurrentFolder().getMessageById(Long.parseLong(messageId));

        if (isThumbnail) {
          List<MimePart> attachmentList = MessageUtils.attachmentsFromPart(msg);
          int index = Integer.valueOf(attachmentIndex);

          MimePart retrievePart = attachmentList.get(index);

          ContentType contentType = new ContentType(retrievePart.getContentType());
          response.setContentType(contentType.getBaseType());

          BufferedInputStream bufInputStream =
              new BufferedInputStream(retrievePart.getInputStream());
          OutputStream outputStream = response.getOutputStream();

          writeScaledImage(bufInputStream, outputStream);

          bufInputStream.close();
          outputStream.flush();
          outputStream.close();
        } else {
          Part imagePart = findImagePart(msg);
          if (imagePart != null) {
            ContentType contentType = new ContentType(imagePart.getContentType());
            response.setContentType(contentType.getBaseType());

            BufferedInputStream bufInputStream =
                new BufferedInputStream(imagePart.getInputStream());
            OutputStream outputStream = response.getOutputStream();

            byte[] inBuf = new byte[1024];
            int len = 0;
            int total = 0;
            while ((len = bufInputStream.read(inBuf)) > 0) {
              outputStream.write(inBuf, 0, len);
              total += len;
            }

            bufInputStream.close();
            outputStream.flush();
            outputStream.close();
          }
        }
      }
    } catch (Exception ex) {
      log.error(ex.getMessage(), ex);
    }
  }
  /**
   * Checks whether the MimePart contains an object of the given mime type.
   *
   * @param part the current MimePart
   * @param mimeType the mime type to check
   * @return {@code true} if the MimePart matches the given mime type, {@code false} otherwise
   * @throws MessagingException parsing the MimeMessage failed
   * @throws IOException parsing the MimeMessage failed
   */
  private boolean isMimeType(final MimePart part, final String mimeType)
      throws MessagingException, IOException {
    // Do not use part.isMimeType(String) as it is broken for MimeBodyPart
    // and does not really check the actual content type.

    try {
      final ContentType ct = new ContentType(part.getDataHandler().getContentType());
      return ct.match(mimeType);
    } catch (final ParseException ex) {
      return part.getContentType().equalsIgnoreCase(mimeType);
    }
  }
  public void multipartMixedTest(MimeBodyPart part1, MimeBodyPart part2) throws Exception {
    MimeMultipart mp = new MimeMultipart();

    mp.addBodyPart(part1);
    mp.addBodyPart(part2);

    MimeBodyPart m = new MimeBodyPart();

    m.setContent(mp);

    MimeMultipart smm =
        generateMultiPartRsa("SHA1withRSA", m, SMIMESignedGenerator.RFC3851_MICALGS);
    SMIMESigned s = new SMIMESigned(smm);

    verifySigners(s.getCertificates(), s.getSignerInfos());

    AttributeTable attr =
        ((SignerInformation) s.getSignerInfos().getSigners().iterator().next())
            .getSignedAttributes();

    Attribute a = attr.get(CMSAttributes.messageDigest);
    byte[] contentDigest =
        ASN1OctetString.getInstance(a.getAttrValues().getObjectAt(0)).getOctets();

    mp = (MimeMultipart) m.getContent();
    ContentType contentType = new ContentType(mp.getContentType());
    String boundary = "--" + contentType.getParameter("boundary");

    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    LineOutputStream lOut = new LineOutputStream(bOut);

    Enumeration headers = m.getAllHeaderLines();
    while (headers.hasMoreElements()) {
      lOut.writeln((String) headers.nextElement());
    }

    lOut.writeln(); // CRLF separator

    lOut.writeln(boundary);
    writePart(mp.getBodyPart(0), bOut);
    lOut.writeln(); // CRLF terminator

    lOut.writeln(boundary);
    writePart(mp.getBodyPart(1), bOut);
    lOut.writeln();

    lOut.writeln(boundary + "--");

    MessageDigest dig = MessageDigest.getInstance("SHA1", BC);

    assertTrue(Arrays.equals(contentDigest, dig.digest(bOut.toByteArray())));
  }
 private void writeBodyPart(byte[] bodyContent, Part part, ContentType contentType)
     throws MessagingException {
   DataSource ds = new ByteArrayDataSource(bodyContent, contentType.toString());
   part.setDataHandler(new DataHandler(ds));
   part.setHeader(CONTENT_TYPE, contentType.toString());
   if (contentType.match("text/*")) {
     part.setHeader(CONTENT_TRANSFER_ENCODING, "8bit");
   } else if (binaryContent) {
     part.setHeader(CONTENT_TRANSFER_ENCODING, "binary");
   } else {
     part.setHeader(CONTENT_TRANSFER_ENCODING, "base64");
   }
 }
 private ContentType getContentType(Exchange exchange) throws ParseException {
   String contentTypeStr = ExchangeHelper.getContentType(exchange);
   if (contentTypeStr == null) {
     contentTypeStr = DEFAULT_CONTENT_TYPE;
   }
   ContentType contentType = new ContentType(contentTypeStr);
   String contentEncoding = ExchangeHelper.getContentEncoding(exchange);
   // add a charset parameter for text subtypes
   if (contentEncoding != null && contentType.match("text/*")) {
     contentType.setParameter("charset", MimeUtility.mimeCharset(contentEncoding));
   }
   return contentType;
 }
Beispiel #8
0
  // Request content type resolution follows similar precedence order to accept type:
  // 1. Request header
  // 2. RestLiRequestOption
  // 3. RestClient configuration
  private void addEntityAndContentTypeHeaders(
      RestRequestBuilder builder, DataMap dataMap, ContentType contentType) throws IOException {
    if (dataMap != null) {
      String header = builder.getHeader(RestConstants.HEADER_CONTENT_TYPE);

      ContentType type;
      if (header == null) {
        if (contentType != null) {
          type = contentType;
        } else if (_contentType != null) {
          type = _contentType;
        } else {
          type = DEFAULT_CONTENT_TYPE;
        }
        builder.setHeader(RestConstants.HEADER_CONTENT_TYPE, type.getHeaderKey());
      } else {
        javax.mail.internet.ContentType headerContentType;
        try {
          headerContentType = new javax.mail.internet.ContentType(header);
        } catch (ParseException e) {
          throw new IllegalStateException("Unable to parse Content-Type: " + header);
        }

        if (headerContentType
            .getBaseType()
            .equalsIgnoreCase(RestConstants.HEADER_VALUE_APPLICATION_JSON)) {
          type = ContentType.JSON;
        } else if (headerContentType
            .getBaseType()
            .equalsIgnoreCase(RestConstants.HEADER_VALUE_APPLICATION_PSON)) {
          type = ContentType.PSON;
        } else {
          throw new IllegalStateException("Unknown Content-Type: " + headerContentType.toString());
        }
      }

      switch (type) {
        case PSON:
          builder.setEntity(PSON_DATA_CODEC.mapToBytes(dataMap));
          break;
        case JSON:
          builder.setEntity(JACKSON_DATA_CODEC.mapToBytes(dataMap));
          break;
        default:
          throw new IllegalStateException("Unknown ContentType:" + type);
      }
    }
  }
 /**
  * Constructor with a String. The MIME type should include a charset parameter specifying the
  * charset to use to encode the string; otherwise, the platform default is used.
  *
  * @param data the string
  * @param type the MIME type
  */
 public ByteArrayDataSource(String data, String type) throws IOException {
   try {
     ContentType ct = new ContentType(type);
     String charset = ct.getParameter("charset");
     String jcharset =
         (charset == null)
             ? MimeUtility.getDefaultJavaCharset()
             : MimeUtility.javaCharset(charset);
     if (jcharset == null) throw new UnsupportedEncodingException(charset);
     this.data = data.getBytes(jcharset);
     this.type = type;
   } catch (ParseException e) {
     IOException e2 = new IOException("can't parse MIME type");
     e2.initCause(e);
     throw e2;
   }
 }
Beispiel #10
0
  /**
   * Gets the message type based on the content type headers.
   *
   * @param msg The message to extract the type from.
   * @return MDN if the message is an MDN message (<a href="http://tools.ietf.org/html/rfc3798">RFC
   *     3798</a>)<br>
   *     DSN if the message is a DNS message (<a href="http://tools.ietf.org/html/rfc3464">RFC
   *     3464</a>)<br>
   *     Normal for all other message type.<br>
   *     Return Unknown if an error occurs.
   */
  public static TxMessageType getMessageType(MimeMessage msg) {
    try {
      ContentType contentType = new ContentType(msg.getContentType());

      if (contentType.match(MDNStandard.MediaType.ReportMessage)
          && contentType.getParameter(MDNStandard.MediaType.ReportType) != null) {

        if (contentType
            .getParameter(MDNStandard.MediaType.ReportType)
            .equalsIgnoreCase(MDNStandard.MediaType.ReportTypeValueNotification))
          return TxMessageType.MDN;
        else if (contentType
            .getParameter(DSNStandard.MediaType.ReportType)
            .equalsIgnoreCase(DSNStandard.MediaType.ReportTypeValueDelivery))
          return TxMessageType.DSN;
      } else if (contentType.match(SMIMEStandard.EncryptedContentMediaType)
          || contentType.match(SMIMEStandard.EncryptedContentMediaTypeAlternative)) {
        return TxMessageType.SMIME;
      }

      return TxMessageType.IMF;
    }
    /// CLOVER:OFF
    catch (ParseException e) {
      LOGGER.warn("Failed to discern message type.", e);
    } catch (MessagingException e) {
      LOGGER.warn("Failed to discern message type.", e);
    }
    return TxMessageType.UNKNOWN;
    /// CLOVER:ON
  }
  public FileContentInfo create(FileContent fileContent) throws FileSystemException {
    MimeFileObject mimeFile = (MimeFileObject) fileContent.getFile();
    Part part = mimeFile.getPart();

    String contentTypeString = null;
    String charset = null;

    try {
      // special handling for multipart
      if (mimeFile.isMultipart()) {
        // get the original content type, but ...
        contentTypeString = part.getContentType();

        // .... we deliver the preamble instead of an inupt string
        // the preamble will be delivered in UTF-8 - fixed
        charset = MimeFileSystem.PREAMBLE_CHARSET;
      }
    } catch (MessagingException e) {
      throw new FileSystemException(e);
    }

    if (contentTypeString == null) {
      // normal message ... get the content type
      try {
        contentTypeString = part.getContentType();
      } catch (MessagingException e) {
        throw new FileSystemException(e);
      }
    }

    ContentType contentType;
    try {
      contentType = new ContentType(contentTypeString);
    } catch (MessagingException e) {
      throw new FileSystemException(e);
    }

    if (charset == null) {
      // charset might already be set by the multipart message stuff, else
      // extract it from the contentType now
      charset = contentType.getParameter("charset"); // NON-NLS
    }

    return new DefaultFileContentInfo(contentType.getBaseType(), charset);
  }
Beispiel #12
0
  // x参数来确定是以html 1 格式显示还是以plain 2
  // 调用时getPart(part,i,1);
  // 显示复杂邮件的正文内容
  public String getPart(Part part, int partNum, int x) throws MessagingException, IOException {

    String s = "";
    String s1 = "";
    String s2 = "";
    String s5 = "";
    String sct = part.getContentType();
    if (sct == null) {
      s = "part 无效";
      return s;
    }
    ContentType ct = new ContentType(sct);
    if (ct.match("text/html") || ct.match("text/plain")) {
      // display text/plain inline
      s1 = "" + (String) part.getContent() + "";
    } else if (partNum != 0) {
      String temp = "";
      if ((temp = part.getFileName()) != null) {
        s2 = "Filename: " + temp + "";
      }
    }
    if (part.isMimeType("multipart/alternative")) {
      String s6 = "";
      String s7 = "";
      Multipart mp = (Multipart) part.getContent();
      int count = mp.getCount();
      for (int i = 0; i < count; i++) {
        if (mp.getBodyPart(i).isMimeType("text/plain")) s7 = getPart(mp.getBodyPart(i), i, 2);
        else if (mp.getBodyPart(i).isMimeType("text/html")) s6 = getPart(mp.getBodyPart(i), i, 1);
      }
      if (x == 1) { // html格式的字符串
        s5 = s6;
      }
      if (x == 2) { // paint类型的字符串
        s5 = s7;
      }
      return s5;
    }
    s = s1 + s2;
    return s;
  }
 @Override
 public void marshal(Exchange exchange, Object graph, OutputStream stream)
     throws NoTypeConversionAvailableException, MessagingException, IOException {
   if (multipartWithoutAttachment || headersInline || exchange.getIn().hasAttachments()) {
     ContentType contentType = getContentType(exchange);
     // remove the Content-Type header. This will be wrong afterwards...
     exchange.getOut().removeHeader(Exchange.CONTENT_TYPE);
     byte[] bodyContent = ExchangeHelper.convertToMandatoryType(exchange, byte[].class, graph);
     Session session = Session.getInstance(System.getProperties());
     MimeMessage mm = new MimeMessage(session);
     MimeMultipart mp = new MimeMultipart(multipartSubType);
     BodyPart part = new MimeBodyPart();
     writeBodyPart(bodyContent, part, contentType);
     mp.addBodyPart(part);
     for (Map.Entry<String, Attachment> entry :
         exchange.getIn().getAttachmentObjects().entrySet()) {
       String attachmentFilename = entry.getKey();
       Attachment attachment = entry.getValue();
       part = new MimeBodyPart();
       part.setDataHandler(attachment.getDataHandler());
       part.setFileName(MimeUtility.encodeText(attachmentFilename, "UTF-8", null));
       String ct = attachment.getDataHandler().getContentType();
       contentType = new ContentType(ct);
       part.setHeader(CONTENT_TYPE, ct);
       if (!contentType.match("text/*") && binaryContent) {
         part.setHeader(CONTENT_TRANSFER_ENCODING, "binary");
       }
       // Set headers to the attachment
       for (String headerName : attachment.getHeaderNames()) {
         List<String> values = attachment.getHeaderAsList(headerName);
         for (String value : values) {
           part.setHeader(headerName, value);
         }
       }
       mp.addBodyPart(part);
       exchange.getOut().removeAttachment(attachmentFilename);
     }
     mm.setContent(mp);
     // copy headers if required and if the content can be converted into
     // a String
     if (headersInline && includeHeaders != null) {
       for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) {
         if (includeHeaders.matcher(entry.getKey()).matches()) {
           String headerStr =
               ExchangeHelper.convertToType(exchange, String.class, entry.getValue());
           if (headerStr != null) {
             mm.setHeader(entry.getKey(), headerStr);
           }
         }
       }
     }
     mm.saveChanges();
     Enumeration<?> hl = mm.getAllHeaders();
     List<String> headers = new ArrayList<String>();
     if (!headersInline) {
       while (hl.hasMoreElements()) {
         Object ho = hl.nextElement();
         if (ho instanceof Header) {
           Header h = (Header) ho;
           exchange.getOut().setHeader(h.getName(), h.getValue());
           headers.add(h.getName());
         }
       }
       mm.saveChanges();
     }
     mm.writeTo(stream, headers.toArray(new String[0]));
   } else {
     // keep the original data
     InputStream is = ExchangeHelper.convertToMandatoryType(exchange, InputStream.class, graph);
     IOHelper.copyAndCloseInput(is, stream);
   }
 }
 @Override
 public Object unmarshal(Exchange exchange, InputStream stream)
     throws IOException, MessagingException {
   MimeBodyPart mimeMessage;
   String contentType;
   Message camelMessage;
   Object content = null;
   if (headersInline) {
     mimeMessage = new MimeBodyPart(stream);
     camelMessage = exchange.getOut();
     MessageHelper.copyHeaders(exchange.getIn(), camelMessage, true);
     contentType = mimeMessage.getHeader(CONTENT_TYPE, null);
     // write the MIME headers not generated by javamail as Camel headers
     Enumeration<?> headersEnum = mimeMessage.getNonMatchingHeaders(STANDARD_HEADERS);
     while (headersEnum.hasMoreElements()) {
       Object ho = headersEnum.nextElement();
       if (ho instanceof Header) {
         Header header = (Header) ho;
         camelMessage.setHeader(header.getName(), header.getValue());
       }
     }
   } else {
     // check if this a multipart at all. Otherwise do nothing
     contentType = exchange.getIn().getHeader(CONTENT_TYPE, String.class);
     if (contentType == null) {
       return stream;
     }
     try {
       ContentType ct = new ContentType(contentType);
       if (!ct.match("multipart/*")) {
         return stream;
       }
     } catch (ParseException e) {
       LOG.warn("Invalid Content-Type " + contentType + " ignored");
       return stream;
     }
     camelMessage = exchange.getOut();
     MessageHelper.copyHeaders(exchange.getIn(), camelMessage, true);
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     IOHelper.copyAndCloseInput(stream, bos);
     InternetHeaders headers = new InternetHeaders();
     extractHeader(CONTENT_TYPE, camelMessage, headers);
     extractHeader(MIME_VERSION, camelMessage, headers);
     mimeMessage = new MimeBodyPart(headers, bos.toByteArray());
     bos.close();
   }
   DataHandler dh;
   try {
     dh = mimeMessage.getDataHandler();
     if (dh != null) {
       content = dh.getContent();
       contentType = dh.getContentType();
     }
   } catch (MessagingException e) {
     LOG.warn("cannot parse message, no unmarshalling done");
   }
   if (content instanceof MimeMultipart) {
     MimeMultipart mp = (MimeMultipart) content;
     content = mp.getBodyPart(0);
     for (int i = 1; i < mp.getCount(); i++) {
       BodyPart bp = mp.getBodyPart(i);
       DefaultAttachment camelAttachment = new DefaultAttachment(bp.getDataHandler());
       @SuppressWarnings("unchecked")
       Enumeration<Header> headers = bp.getAllHeaders();
       while (headers.hasMoreElements()) {
         Header header = headers.nextElement();
         camelAttachment.addHeader(header.getName(), header.getValue());
       }
       camelMessage.addAttachmentObject(getAttachmentKey(bp), camelAttachment);
     }
   }
   if (content instanceof BodyPart) {
     BodyPart bp = (BodyPart) content;
     camelMessage.setBody(bp.getInputStream());
     contentType = bp.getContentType();
     if (contentType != null && !DEFAULT_CONTENT_TYPE.equals(contentType)) {
       camelMessage.setHeader(CONTENT_TYPE, contentType);
       ContentType ct = new ContentType(contentType);
       String charset = ct.getParameter("charset");
       if (charset != null) {
         camelMessage.setHeader(Exchange.CONTENT_ENCODING, MimeUtility.javaCharset(charset));
       }
     }
   } else {
     // If we find no body part, try to leave the message alone
     LOG.info("no MIME part found");
   }
   return camelMessage;
 }
Beispiel #15
0
  /**
   * 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 byte[] aMsgData,
      @Nonnull final AS2Message aMsg,
      @Nonnull final IAS2HttpResponseHandler aResponseHandler) {
    // TODO store HTTP request, headers, and data to file in Received folder
    // -> use message-id for filename?
    try {
      final IAS2Session aSession = m_aReceiverModule.getSession();

      try {
        // Put received data in a MIME body part
        final ContentType aReceivedContentType =
            new ContentType(aMsg.getHeader(CAS2Header.HEADER_CONTENT_TYPE));
        final String sReceivedContentType = aReceivedContentType.toString();

        final MimeBodyPart aReceivedPart = new MimeBodyPart();
        aReceivedPart.setDataHandler(
            new DataHandler(new ByteArrayDataSource(aMsgData, sReceivedContentType, null)));

        // Header must be set AFTER the DataHandler!
        aReceivedPart.setHeader(CAS2Header.HEADER_CONTENT_TYPE, sReceivedContentType);
        aMsg.setData(aReceivedPart);
      } catch (final Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_PARSING_MIME_FAILED,
            ex);
      }

      // Extract AS2 ID's from header, find the message's partnership and
      // update the message
      try {
        final String sAS2From = aMsg.getAS2From();
        aMsg.getPartnership().setSenderAS2ID(sAS2From);

        final String sAS2To = aMsg.getAS2To();
        aMsg.getPartnership().setReceiverAS2ID(sAS2To);

        // Fill all partnership attributes etc.
        aSession.getPartnershipFactory().updatePartnership(aMsg, false);
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("authentication-failed"),
            AbstractActiveNetModule.DISP_PARTNERSHIP_NOT_FOUND,
            ex);
      }

      // 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);

      if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
        if (s_aLogger.isTraceEnabled())
          s_aLogger.trace("Decompressing received message before checking signature...");
        decompress(aMsg);
        bIsDecompressed = true;
      }

      verify(aMsg);

      if (aCryptoHelper.isCompressed(aMsg.getContentType())) {
        // Per RFC5402 compression is always before encryption but can be before
        // or after signing of message but only in one place
        if (bIsDecompressed) {
          throw new DispositionException(
              DispositionType.createError("decompression-failed"),
              AbstractActiveNetModule.DISP_DECOMPRESSION_ERROR,
              new Exception(
                  "Message has already been decompressed. Per RFC5402 it cannot occur twice."));
        }

        if (s_aLogger.isTraceEnabled())
          if (aMsg.containsAttribute(AS2Message.ATTRIBUTE_RECEIVED_SIGNED))
            s_aLogger.trace("Decompressing received message after verifying signature...");
          else s_aLogger.trace("Decompressing received message after decryption...");
        decompress(aMsg);
        bIsDecompressed = true;
      }

      if (s_aLogger.isTraceEnabled())
        try {
          s_aLogger.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) {
          s_aLogger.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 NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_VALIDATION_FAILED
                + "\n"
                + StackTraceHelper.getStackAsString(ex),
            ex);
      }

      // Store the received message
      try {
        aSession.getMessageProcessor().handle(IProcessorStorageModule.DO_STORE, aMsg, null);
      } catch (final NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_STORAGE_FAILED + "\n" + ex.getMessage(),
            ex);
      }

      // Validate the received message after storing
      try {
        aSession
            .getMessageProcessor()
            .handle(IProcessorStorageModule.DO_VALIDATE_AFTER_STORE, aMsg, null);
      } catch (final NoModuleException ex) {
        // No module installed - ignore
      } catch (final OpenAS2Exception ex) {
        throw new DispositionException(
            DispositionType.createError("unexpected-processing-error"),
            AbstractActiveNetModule.DISP_VALIDATION_FAILED
                + "\n"
                + StackTraceHelper.getStackAsString(ex),
            ex);
      }

      try {
        if (aMsg.isRequestingMDN()) {
          // Transmit a success MDN if requested
          sendSyncMDN(
              sClientInfo,
              aResponseHandler,
              aMsg,
              DispositionType.createSuccess(),
              AbstractActiveNetModule.DISP_SUCCESS);
        } else {
          // Just send a HTTP OK
          HTTPHelper.sendSimpleHTTPResponse(aResponseHandler, HttpURLConnection.HTTP_OK);
          s_aLogger.info("sent HTTP OK " + sClientInfo + aMsg.getLoggingText());
        }
      } catch (final Exception ex) {
        throw new WrappedOpenAS2Exception(
            "Error creating and returning MDN, message was stilled processed", ex);
      }
    } catch (final DispositionException ex) {
      sendSyncMDN(sClientInfo, aResponseHandler, aMsg, ex.getDisposition(), ex.getText());
      m_aReceiverModule.handleError(aMsg, ex);
    } catch (final OpenAS2Exception ex) {
      m_aReceiverModule.handleError(aMsg, ex);
    }
  }