2

i am using a http outbound endpoint to call a separate service that needs to process a file that is sent to mule in a multipart request. Here is an example

<http:outbound-endpoint connector-ref="serviceConnector"
                address="http://${serviceHost}:${servicePort}/upload"
                method="POST"
                responseTimeout="${endpointTimeout}"
                mimeType="multipart/form-data">

The problem i am having is that when this service is called i am getting a FileUploadException saying that the request was reject because no multipart boundary has been found.

I have been experimenting with this problem and looking at different questions but none of them seems to resolve the issue.

Mule ESB and "multipart/form-data"

Mule http:outbound-endpoint + multipart/form-data

https://www.mulesoft.org/jira/browse/MULE-6917

I have also tried altering the connector like explained in this question: Send file to Mule inbound-endpoint but no luck.

Any ideas?

Thanks

Community
  • 1
  • 1
Loshmeey
  • 341
  • 1
  • 5
  • 18

2 Answers2

2

Finally this problem was solved by creating a custom processor that was parsing the incoming request, splitting it into parts and manually reading the bytes of the parts input stream and setting the read bytes as a data source that is attached to the message. The code:

 InputStream in = message.getPayload( InputStream.class );
 MultiPartInputStream multiIn = new MultiPartInputStream( in, contentType, null );
try
    {
        Collection<Part> parts = multiIn.getParts();

        for ( Part part : parts )
        {
           if ( part instanceof MultiPart )
                {
                    is = part.getInputStream();
                    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                    byte[] isByteArray = new byte[1024];
                    int numberRead;
                    while ( (numberRead = is.read( isByteArray ) ) != -1 ){
                        buffer.write(isByteArray, 0, numberRead);
                    }
                    byte[] bytesRead = buffer.toByteArray();
                    DataHandler attachment = new DataHandler(new ByteArrayDataSource( bytesRead, "application/octet-stream")); 
                    message.addOutboundAttachment( part.getName(), attachment );
                }
         }
   }...handle exceptions etc...

Hopefully this helps someone!

Loshmeey
  • 341
  • 1
  • 5
  • 18
0

You don't show enough of your flow to really be sure about what's missing but at first glance, I'd say you are not setting the boundary attribute in the outbound request Content-Type header.

Read the following to better understand how multipart/form-data requests work: http://chxo.com/be2/20050724_93bf.html

David Dossot
  • 33,403
  • 4
  • 38
  • 72
  • Thank you for the response David! There is not much left in the flow apart from a few loggers and a response builder. This is the value of the `Content-Type` header in the message: `Content-Type=multipart/form-data; boundary=----WebKitFormBoundaryLzHwJdbCLdUuFvR2` . I have executed this request from a postman rest client, and i am getting the same error saying no boundary was found. Is there anything special i should include in my mule flow to make the request sent from outbound connector identical to the one coming to mule? Thanks! – Loshmeey Jan 14 '15 at 00:16
  • 1
    From what you are saying, I reckon you are missing a copy-properties message processor to copy the HTTP headers received in the inbound properties to the outbound scope. See http://stackoverflow.com/a/6552437/387927 – David Dossot Jan 14 '15 at 15:13
  • After adding copy-properties processor, i have managed to post the request - and get a different exception :). First i have tried copying Content-Type and Content-Length header values, but in that case the request was timing out, and if i copy the Content type only the request is successfully posted, but tomcat returns an error saying "The request sent by the client was syNtactically incorrect". Should i be copying some other header properties? I have also tried copying the whole http.headers value but it did not give any results. Thanks! – Loshmeey Jan 14 '15 at 17:54
  • After some debugging and request intercepting in the target application, i have noticed that hashmaps that should contain the file and the text part of the multipart request are empty, which leads me to believe that maybe i should also copy the payload of the message? – Loshmeey Jan 14 '15 at 19:10
  • Since you don't show how is your HTTP connector configured nor your flow, the assumption is that you do not do anything with the inbound HTTP payload and receive it as a stream. If this assumption is correct, the streaming payload should be used as-is in the outbound HTTP endpoint. So there should be no need to do anything to the payload. – David Dossot Jan 14 '15 at 20:12
  • All the assumptions are correct! My connector only has a keepAliveTimeout property. I am getting the inbound payload as ChunckedInputStream from the client, i am only copying the Content-Type header and calling the outbound connector that i showed in the question. Hmm, i am still not getting any files, or any content in the target application. – Loshmeey Jan 14 '15 at 21:29
  • Try putting a proxy (like TCPMon) between Mule and Tomcat to find out what's wrong exactly with the request. Also have you considered using the ready made `pattern:http-proxy` instead of re-inventing the wheel? – David Dossot Jan 14 '15 at 23:26