Showing posts with label mtom. Show all posts
Showing posts with label mtom. Show all posts

Monday, June 25, 2018

Regex to get MTOM binary content

Leave a Comment

I am trying to get the MTOM binary content using a extended class of SoapClient, the response is something like that:

    --uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2     Content-ID:      <http://tempuri.org/0>     Content-Transfer-Encoding: 8bit     Content-Type: application/xop+xml;charset=utf-8;type="text/xml"          <big-xml-here>             <xop:Include href="cid:http://tempuri.org/1/636644204289948690" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>          </big-xml-here>  --uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2-- 

Right after the XML, the MTOM response continue with the binaries related to the "cid" URL:

Content-ID: <http://tempuri.org/1/636644204289948690> Content-Transfer-Encoding: binary Content-Type: application/octet-stream  %PDF-1.4 %���� (lots of binary content here)  --uuid:7329cfb8-46a4-40a8-b15b-39b7b0988b57+id=4-- 

To extract everything I've tried this code:

$xop_elements = null;         preg_match_all('/<xop[\s\S]*?\/>/', $response, $xop_elements);          $xop_elements = reset($xop_elements);          if (is_array($xop_elements) && count($xop_elements)) {              foreach ($xop_elements as $xop_element) {                  $cid = null;                 preg_match('/cid:(.*?)"/', $xop_element, $cid);                  if(isset($cid[1])){                     $cid = $cid[1];                     $binary = null;                     preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/", $response, $binary);                     var_dump($binary);                     exit();                 }             }         } 

Although the preg_match_all and the first preg_match are working, the last one:

/Content-ID:.*?$cid.*?(.*?)uuid/  

is not working

On the original source: https://github.com/debuss/MTOMSoapClient/blob/master/MTOMSoapClient.php

the regex is

/Content-ID:[\s\S].+?'.$cid.'[\s\S].+?>([\s\S]*?)--uuid/ 

but I got an error on PHP 7:

preg_match(): Unknown modifier '/'

Is there a away to get MTOM binary of each CID?

Thanks in advance!

2 Answers

Answers 1

You need to first unquote $cid as that is causing the your first error

$cid = preg_quote($cid[1], '/'); 

Next you need to use the s modifier flag so that . matches new lines also

preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/s", $response, $binary); 

s (PCRE_DOTALL) If this modifier is set, a dot metacharacter in the pattern matches all characters, including newlines. Without it, newlines are excluded. This modifier is equivalent to Perl's /s modifier. A negative class such as [^a] always matches a newline character, independent of the setting of this modifier.

Answers 2

As I understand, you are trying to adjust the original code to your modified file SOAP version.

Instead of a number, you want to capture the whole http://tempuri.org/1/636644204289948690 in the $cid variable (you may want to rename the var). To do so you could use the following regex, that matches everything but a double quote in capture group 1: cid:([^"]+)

preg_match('/cid:([^"]+)/', $xop_element, $cid); 

So far, so good. Guessing from your description you should use the following pattern to capture the binary part:

'%Content-ID: <'.$cid.'>([\s\S]*?)--uuid%' 

We use a modified dot [\s\S] to match across multiple lines (as shown as well in the original implementation). Otherwise, add the s|single line flag or (?s) inline modifier. Also, I use alternative regex delimiters % to avoid escaping problems. It's still sound to use preg_quote($cid[1], '%') as suggested by Tarun.

Demo

Now, you can retrieve the block in question from capture group 1:

trim($binary[1]); 
Read More

Thursday, April 7, 2016

MTOM - Root content type was always text/xml

Leave a Comment

I am using MTOM to stream the attached file from client to the server.

The MTOM gets applied and the file is streamed as binary. But the root Content-Type was always "text/xml" which should be "application/xml+xop".

The problems occurs only in websphere. The content type was set as "text/xml" in websphere.

In websphere liberity profile, the content type was set as "application/xml+xop"

------=_Part_7283_-2062365125.1458743649653 Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: binary Content-Id: <511212039242.1458743649653.IBM.WEBSERVICES@lsrv4665.linux.rabobank.nl>      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">         <soapenv:Header>         </soapenv:Header>         <soapenv:Body>           <Content><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:58cf03d2-322f-4819-80fb-3b001f497d12%40www.test.com"/>           </Content>         </soapenv:Body>     </soapenv:Envelope>      Content-Type: application/pdf; name=attachment.pdf  Content-Transfer-Encoding: binary 

2 Answers

Answers 1

I have gathered couple of answers. Hope first answer will be fit for you. For precautions, i have also added some other answer with links. Hope it will save you.

Ans-1:

server side (JAX-WS in Weblogic)

use @MTOM annotation or mtom.xml policy

client side (JAX-WS in Weblogic)

Pass MTOMFeature() as argument: MtomService port = service.getMailServicePort(new MTOMFeature()); 

MTOM attachment via SOAPUI, 3 steps:

  1. Set Enable MTOM = true in the request properties
  2. Upload the attachment (e.g.. A3.pdf), notice the contentID
  3. Set the MTOM contentID in the xml request

Here is a full example with images with weblogic. Hope it will fit with your issue.(link for Sending attachment: MTOM / XOP vs SWA and inline attachment)

Another Resource Link:

  1. Steps to Use MTOM/XOP to Send Binary Data
  2. Error consuming webservice, content type “application/xop+xml” does not match expected type “text/xml”

Ans-2:

Pulling in saaj-impl 1.3.23 and preferring application classes for javax.xml.soap.* resolved this issue.

Resource Link: https://jira.spring.io/browse/SWS-855


Ans-3:

From mkyong's tutorial, it can be solved enabling mtom on client and server.

Enabling MTOM on server:

Enable server to send attachment via MTOM is very easy, just annotate the web service implementation class with javax.xml.ws.soap.MTOM.

Enabling MTOM on client:

Enable client to send attachment via MTOM to server is required some extra efforts, see following example :

//codes enable MTOM in client BindingProvider bp = (BindingProvider) imageServer; SOAPBinding binding = (SOAPBinding) bp.getBinding(); binding.setMTOMEnabled(true); 

Ans-4

Credit goes to @BalusC. He has given an awesome answer with his great tutorial.

The meta tag is ignored when the page is served over HTTP.

When using JSP,

you should put <%@ page pageEncoding="UTF-8" %> in top.

When using Servlet,

you should do response.setCharacterEncoding("UTF-8");.

Both will implicitly set the right charset in the content type header. You may find this article useful: Unicode - How to get characters right?. For JSP/Servlet solutions, start at this chapter.

Resource Link:

  1. How to set the "Content-Type ... charset" in the request header using a HTML link

For research, you can go through followings

For a Java servlet, you should have the line

response.setContentType("text/html");

at the top of your doGet or doPost method, where response is a reference to the HttpServletResponse.

Related Link:

  1. How to set up your server to send the correct MIME types
  2. Character Encoding problem with IBM's JSF and Ajax

Another answer

I've figured out what is causing the issue, but I do not understand why. The behavior exhibits itself when there is an on-error action on the request. Attached is a zip of a simple MPG with a request, response, and error rule that demonstrate this. The request has an on-error action, a simple xform that does a dp:reject (to force the error), and a results action. The error rule has a results action and a set var action. If you leave the on-error in, the response content-type is returned as "text/xml". If you remove the on-error, the content-type correctly returns "application/json". (Copied from following resource link)

Resource Link:

  1. How to set header Content-Type in error rule

Answers 2

Able to resolve this issue by using saaj-impl jar.

pom.xml

 <dependency>     <groupId>com.sun.xml.messaging.saaj</groupId>     <artifactId>saaj-impl</artifactId>     <version>1.3.16</version>     <scope>provided</scope>  </dependency> 

dispatcher-servlet.xml

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">   <property name="messageFactory">     <bean class="com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl" />   </property> </bean> 
Read More