You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Mikael Larsson <mi...@incomit.com> on 2004/02/11 11:17:11 UTC

contentlength calculation error with attachments

Hi all!

I'm using axis for sending and receiving SOAP message based requests
with attachments (multipart mixed). When sending a message through the
TCPMonitor I can see that the length is set to some value e.g.
"Content-Length: 2821", on the receiving side (the server is also
implemented using axis) the following is reported (the error occurs when
trying to read the attachments):

<soapenv:Fault>
   <faultcode>soapenv:Server.userException</faultcode>
   <faultstring>javax.xml.soap.SOAPException: Simulator failed to
process message: ; nested exception is: 
	java.io.IOException: End of stream encountered before final
boundary marker.</faultstring>
   <detail/>
  </soapenv:Fault>

Now, if I simply resend the message from the TCPMonitor (without any
modifications) I can see that the length is recalculated, e.g. to:
"Content-Length: 3323" and this is the only change to the message being
sent. The server accepts this and is able to read the attachments.

I suspect that there may be something wrong in the code that adds my
attachments, the code that adds the attachments looks like:

org.apache.axis.attachments.AttachmentPart ap =
new org.apache.axis.attachments.AttachmentPart();
MimeMultipart mimeMultipart = new MimeMultipart("mixed"); MimeBodyPart
mimeOuterBodyPart = new MimeBodyPart();
mimeOuterBodyPart.setContent(mimeMultipart);
ap.setDataHandler(mimeOuterBodyPart.getDataHandler());
//Add MimeBodyParts to the mixed MimeMultipart
for (int i = 0; i < content.length; i++) {
    MimeBodyPart mimeBodyPart = encodeContentInMimeBodyPart(content[i]);
    mimeMultipart.addBodyPart(mimeBodyPart);
}
soapCall.addAttachmentPart(ap);
Vector returnElements = (Vector) soapCall.invoke(input);


Where encodeContentInMimeBodyPart:

private static MimeBodyPart encodeContentInMimeBodyPart(MM7SOAPContent
content)throws java.io.IOException, javax.mail.MessagingException {
    MimeBodyPart mimeBodyPart = null;
    mimeBodyPart = new MimeBodyPart();
    //Use the ByteArrayDataSource helper class
    DataSource dataSource = new
    ByteArrayDataSource((byte[])content.getContentData(),
                         (String)content.getContentType());
    DataHandler dh = new javax.activation.DataHandler(dataSource);
    mimeBodyPart.setDataHandler(dh);
    //Set correct content ID
    mimeBodyPart.setHeader("Content-ID", content.getContentID());
    mimeBodyPart.setHeader("Content-Location", content.getContentID());
    return mimeBodyPart;
}


The message I'm trying to send has the following structure:

SOAP HEADER
SOAP Body
Attachments wrapped in a multipart/mixed part (where attachments shall
be encoded as base64 for "binary files" such as jpegs and gifs)

When the client is implemented with Apache SOAP and the server is
implemented with Axis all is OK... When the client is implemented with
Axis and the server is implemented with Apache SOAP all is OK... When
the both are implemented with axis it is NOT ok... I guess that Apache
soap calculates the correct length and that it does not use the
Content-Length indicator in the header for incoming messages.

When sent the message looks something like:

POST /myService HTTP/1.0

Content-Type: multipart/related; type="text/xml";
start="<03902322C81B1C03BF5E1ECEA2525D8C>";
boundary="----=_Part_1_291640.1076432277199"

Accept: application/soap+xml, application/dime, multipart/related,
text/*
User-Agent: Axis/1.1
Host: 192.168.1.4
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 3323

------=_Part_1_291640.1076432277199
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <03902322C81B1C03BF5E1ECEA2525D8C>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Header>
 ..... some header data
   </soapenv:Header>
 <soapenv:Body>
...... some body data
 </soapenv:Body>
</soapenv:Envelope>
------=_Part_1_291640.1076432277199
Content-Type: multipart/mixed; 
	boundary="----=_Part_0_14929221.1076432276839"
Content-Transfer-Encoding: binary
Content-Id: <8738B6AC43F47E27BA8B5153AB36A40D>

------=_Part_0_14929221.1076432276839
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-ID: message_content_id_0
Content-Location: message_content_id_0

...some text
------=_Part_0_14929221.1076432276839
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-ID: message_content_id_1
Content-Location: message_content_id_1

...some image data 

------=_Part_0_14929221.1076432276839--

------=_Part_1_291640.1076432277199--


Any suggestions? What needs to be done in order to get a correct length
calculation?

Regards,
/Mikael Larsson
Incomit




RE: contentlength calculation error with attachments

Posted by Mikael Larsson <mi...@incomit.com>.
Hi again!

It seems like my problem was caused by the fact that the Content-Length
is calculated before a call to MimeBodyPart.updateHeaders is done. I'm
not sure where the call is made in axis that actually leads to the
update of all mime headers but it seems to be done after calculation of
the Content-Length, at least in the case of SOAP messaging.


I do not understand the inner workings of multipart attachments but when
updating the encodeContentInMimeBodyPart method to explicitly update the
headers:

private static MimeBodyPart encodeContentInMimeBodyPart(MM7SOAPContent
content)throws java.io.IOException, javax.mail.MessagingException {

    MyMimeBodyPart mimeBodyPart = new MyMimeBodyPart();
    //Use the ByteArrayDataSource helper class
    DataSource dataSource = new
ByteArrayDataSource(content.getContentData(),
    content.getContentType());
    DataHandler dh = new javax.activation.DataHandler(dataSource);
    mimeBodyPart.setDataHandler(dh);
    //Set correct content ID
    mimeBodyPart.setHeader("Content-ID", content.getContentID());
    mimeBodyPart.updateHeaders();
    return mimeBodyPart;
}


Where
class MyMimeBodyPart extends MimeBodyPart {
    public void updateHeaders() throws javax.mail.MessagingException {
        super.updateHeaders();
    }
}

The Content-length is calculated correct.

Is this a bug in axis? Wrong Content-Length calculated when including
multipart attachments?

/Mikael




> -----Original Message-----
> From: Mikael Larsson [mailto:mikael.larsson@incomit.com]
> Sent: den 11 februari 2004 11:17
> To: axis-user@ws.apache.org
> Subject: contentlength calculation error with attachments
> 
> Hi all!
> 
> I'm using axis for sending and receiving SOAP message based requests
> with attachments (multipart mixed). When sending a message through the
> TCPMonitor I can see that the length is set to some value e.g.
> "Content-Length: 2821", on the receiving side (the server is also
> implemented using axis) the following is reported (the error occurs
when
> trying to read the attachments):
> 
> <soapenv:Fault>
>    <faultcode>soapenv:Server.userException</faultcode>
>    <faultstring>javax.xml.soap.SOAPException: Simulator failed to
> process message: ; nested exception is:
> 	java.io.IOException: End of stream encountered before final
> boundary marker.</faultstring>
>    <detail/>
>   </soapenv:Fault>
> 
> Now, if I simply resend the message from the TCPMonitor (without any
> modifications) I can see that the length is recalculated, e.g. to:
> "Content-Length: 3323" and this is the only change to the message
being
> sent. The server accepts this and is able to read the attachments.
> 
> I suspect that there may be something wrong in the code that adds my
> attachments, the code that adds the attachments looks like:
> 
> org.apache.axis.attachments.AttachmentPart ap =
> new org.apache.axis.attachments.AttachmentPart();
> MimeMultipart mimeMultipart = new MimeMultipart("mixed"); MimeBodyPart
> mimeOuterBodyPart = new MimeBodyPart();
> mimeOuterBodyPart.setContent(mimeMultipart);
> ap.setDataHandler(mimeOuterBodyPart.getDataHandler());
> //Add MimeBodyParts to the mixed MimeMultipart
> for (int i = 0; i < content.length; i++) {
>     MimeBodyPart mimeBodyPart =
encodeContentInMimeBodyPart(content[i]);
>     mimeMultipart.addBodyPart(mimeBodyPart);
> }
> soapCall.addAttachmentPart(ap);
> Vector returnElements = (Vector) soapCall.invoke(input);
> 
> 
> Where encodeContentInMimeBodyPart:
> 
> private static MimeBodyPart encodeContentInMimeBodyPart(MM7SOAPContent
> content)throws java.io.IOException, javax.mail.MessagingException {
>     MimeBodyPart mimeBodyPart = null;
>     mimeBodyPart = new MimeBodyPart();
>     //Use the ByteArrayDataSource helper class
>     DataSource dataSource = new
>     ByteArrayDataSource((byte[])content.getContentData(),
>                          (String)content.getContentType());
>     DataHandler dh = new javax.activation.DataHandler(dataSource);
>     mimeBodyPart.setDataHandler(dh);
>     //Set correct content ID
>     mimeBodyPart.setHeader("Content-ID", content.getContentID());
>     mimeBodyPart.setHeader("Content-Location",
content.getContentID());
>     return mimeBodyPart;
> }
> 
> 
> The message I'm trying to send has the following structure:
> 
> SOAP HEADER
> SOAP Body
> Attachments wrapped in a multipart/mixed part (where attachments shall
> be encoded as base64 for "binary files" such as jpegs and gifs)
> 
> When the client is implemented with Apache SOAP and the server is
> implemented with Axis all is OK... When the client is implemented with
> Axis and the server is implemented with Apache SOAP all is OK... When
> the both are implemented with axis it is NOT ok... I guess that Apache
> soap calculates the correct length and that it does not use the
> Content-Length indicator in the header for incoming messages.
> 
> When sent the message looks something like:
> 
> POST /myService HTTP/1.0
> 
> Content-Type: multipart/related; type="text/xml";
> start="<03902322C81B1C03BF5E1ECEA2525D8C>";
> boundary="----=_Part_1_291640.1076432277199"
> 
> Accept: application/soap+xml, application/dime, multipart/related,
> text/*
> User-Agent: Axis/1.1
> Host: 192.168.1.4
> Cache-Control: no-cache
> Pragma: no-cache
> SOAPAction: ""
> Content-Length: 3323
> 
> ------=_Part_1_291640.1076432277199
> Content-Type: text/xml; charset=UTF-8
> Content-Transfer-Encoding: binary
> Content-Id: <03902322C81B1C03BF5E1ECEA2525D8C>
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <soapenv:Envelope
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
>  <soapenv:Header>
>  ..... some header data
>    </soapenv:Header>
>  <soapenv:Body>
> ...... some body data
>  </soapenv:Body>
> </soapenv:Envelope>
> ------=_Part_1_291640.1076432277199
> Content-Type: multipart/mixed;
> 	boundary="----=_Part_0_14929221.1076432276839"
> Content-Transfer-Encoding: binary
> Content-Id: <8738B6AC43F47E27BA8B5153AB36A40D>
> 
> ------=_Part_0_14929221.1076432276839
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
> Content-ID: message_content_id_0
> Content-Location: message_content_id_0
> 
> ...some text
> ------=_Part_0_14929221.1076432276839
> Content-Type: image/gif
> Content-Transfer-Encoding: base64
> Content-ID: message_content_id_1
> Content-Location: message_content_id_1
> 
> ...some image data
> 
> ------=_Part_0_14929221.1076432276839--
> 
> ------=_Part_1_291640.1076432277199--
> 
> 
> Any suggestions? What needs to be done in order to get a correct
length
> calculation?
> 
> Regards,
> /Mikael Larsson
> Incomit
> 
>