import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import javax.mail.util.ByteArrayDataSource; import javax.mail.util.SharedByteArrayInputStream; import java.io.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.ArrayList; import java.util.Base64; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.charset.StandardCharsets; import org.apache.commons.lang.StringEscapeUtils; import com.itko.lisa.vse.stateful.model.Request; import com.itko.util.ParameterList; import com.itko.util.Parameter; // dump parameterList to log for debug purposes void dumpParameterList(ParameterList parameterList) { Iterator itr = parameterList.iterator(); testExec.log("start dumping parameterList list","===================================="); while(itr.hasNext()) { Parameter param = itr.next(); testExec.log(param.getKey(),param.getValue()); } testExec.log("end dumping parameterList list","===================================="); } // Save InputStrean into a file object void saveArrayInputStreamToFile(File f, SharedByteArrayInputStream sharedByteArrayInputStream) { FileOutputStream fos = new FileOutputStream(f) ; byte[] buffer = new byte[4096]; int n; int total = 0; InputStream rawInputStream = sharedByteArrayInputStream; // log content for debugging purposes try { testExec.log("rawInputStream available number of bytes",rawInputStream.available().toString()); } catch (Exception e) { testExec.log("rawInputStream is null", e.toString()); } // reading rawInputStream while ((n = rawInputStream.read(buffer)) > 0) { total += n; fos.write(buffer, 0, n); } fos.close(); rawInputStream.close(); } //dump metadata to log (for debuging) ParameterList metadata = lisa_vse_request.getMetaData(); dumpParameterList(metadata); if (metadata.get("Content-Type").matches(".*multipart.*")) { //Get the input HTTP request. it can be of content type application/xop+xml or application/text, etc... ByteArrayDataSource bads = new ByteArrayDataSource(testExec.getStateObject("lisa.vse.http.current.transaction.raw"), "application/xop+xml" ) ; // create a new MimeMultipart object with ByteArrayDataSource MimeMultipart msg = new MimeMultipart(bads); // if the message is MimeMultipart, then copy parts into their individual files/chunks if (msg instanceof MimeMultipart) { try { for (int partCount = 0; partCount < msg.getCount(); partCount++) { MimeBodyPart mimebodyPart = (MimeBodyPart) msg.getBodyPart(partCount); //if SOAP/xml part - process SOAPPart if (!mimebodyPart.ATTACHMENT.equalsIgnoreCase(mimebodyPart.getDisposition())) { // we want to get the SOAP message "SOAPMSG" to construct the lisa.vse.request object later on InputStream in = mimebodyPart.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[8192]; for (;;) { int nread = in.read(buf, 0, buf.length); if (nread <= 0) { break; } baos.write(buf, 0, nread); } in.close(); baos.close(); byte[] bytes = baos.toByteArray(); String str = new String(bytes, StandardCharsets.UTF_8); // store SOAP part in soapPart property. testExec.setStateValue("soapPart", str); } //Save attachment to a file else if (testExec.getStateBoolean("Save_Attachments",false)) { // save attachments // create directory to save attachment to String directoryName = LISA_RELATIVE_PROJ_PATH + "/Data/RequestAttachments"; { //create dir if not exists File d = new File(directoryName); if (!d.exists()) d.mkdir(); } //get filename of the attachment String attachedFilename; if (mimebodyPart.getFileName() != null) { attachedFilename = mimebodyPart.getFileName(); } else { // if unable to determine filename, then try to get it from the Content-Disposition Pattern pattern = Pattern.compile("name=\"(.+?)\""); String contentDispositionStr = mimebodyPart.getHeader("Content-Disposition",";").trim(); Matcher matcher = pattern.matcher(contentDispositionStr); if (matcher.find()) { attachedFilename = matcher.group(1); } else { // if we still can't get the filename, last desparate attempt on the ContentID attachedFilename = mimebodyPart.getContentID().trim().replaceAll("[/\\\"'*;\\-\\?\\[\\]\\(\\)\\~\\!\\$\\{\\}\\&<>#@&\\|]",""); //.replaceAll("[^\\p{L}\\p{Nd}]+", "") } } testExec.log("attachedFilename", attachedFilename); File f = new File(directoryName + "/" + attachedFilename); // if content encoding is binary if (mimebodyPart.getEncoding().equalsIgnoreCase("binary") && mimebodyPart.getContentType().contains("octet-stream")) { mimebodyPart.saveFile(f); // saveArrayInputStreamToFile(f, (SharedByteArrayInputStream) mimebodyPart.getContent()); } else if (mimebodyPart.getEncoding().equalsIgnoreCase("binary") && mimebodyPart.getContentType().matches("(.*image.*|.*jpeg.*)")) { mimebodyPart.saveFile(f); } // if content encoding is text else if (mimebodyPart.getContent() instanceof String) { OutputStream os = null; try { os = new FileOutputStream(f); String str = (String) mimebodyPart.getContent(); os.write(str.getBytes(), 0, str.length()); } catch (IOException e) { testExec.log("IOException error", e.toString()); }finally{ try { os.close(); } catch (IOException e) { testExec.log("IOException error", e.toString()); } } } } } } catch (MessagingException e) { testExec.log("Something is wrong, maybe input isn't Multi-Part MTOM", e.getMessage()); } } else { testExec.log("Input message", "The request msg is NOT instanceof MimeMultipart"); return -1; } } return 0;