You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@ws.apache.org by Wouter Cloetens <wc...@raleigh.ibm.com> on 2000/07/30 10:57:02 UTC

Multipart Mime support

Sorry for the large document and diff in the next mail. I don't have any webspace on the 
Net I can easily dump this stuff on.

I've made a first pass at multipart mime support. This version takes a minimal 
effort approach and is by no means ready to be merged with the tree, for 
reasons discussed below.

This version depends on JavaMail (http://java.sun.com/products/javamail/) and 
the Java Activiation Framework (http://java.sun.com/products/beans/glasgow/jaf.html). 
You will need mail.jar and activation.jar.

The serialiser takes an InputStream, a (JAF) DataSource, a (JAF) DataHandler 
or a (JavaMail) MimeBodyPart. These objects are assigned a unique Mime 
Content-ID and attached as Mime parts. The SOAP request itself becomes the 
first Mime part.
The content itself is set to "multipart/related" (with a boundary identifier) if there 
are any attachments. The SOAP HTTP headers remain in the HTTP request, 
not in the Mime headers of the SOAP part.
The attachments are referred to by their Content-ID with a new type of 
"attachment". For example:

<return
 xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/"
 xsi:type="ns2:attachment"
 href="cid:2936953.964977132419.wcloeten@255.255.255.255"
/>

I'm not sure if this is a desirable format (in fact, I'm pretty sure it isn't), but I lack 
support in the SOAP specification and just about everybody who suggested 
how to do multipart support uses a different type, most of those a violation of the 
logic of some specification. "href" is supposed to refer to a URI, and I figured 
making up a "cid" protocol wasn't too bad. Trying to figure out if the "attachment" 
type should be specified in some schema makes my head hurt, and value 
reference format in the SOAP spec may not entirely agree with it. Suggestions 
more than welcome.
These attachments are always deserialised as DataHandler objects. From this, 
you can derive a DataSource, the Mime content type, an InputStream, an object, 
a bean, or you can even handle it with content handlers supporting the content 
type. The Java Activation Framework is really quite nifty.

Notes:
1. The code should be decoupled more. Multipart support (only for HTTP so far) 
is scattered over the rpcrouter, SOAPHTTPConnection and HTTPUtils. Other 
transport types will have to duplicate significant amounts of code as it stands 
today.
2. Other transport types will likely require different transfer-encodings (e.g. e-mail 
encoding may impose a 7-bit limit). See my discussion on an encoding context 
below, under 6.
3. I've ported rpcrouter.jsp to a servlet. I'm not sure if that'll work out of the box 
anywhere else than on my development platform (WebSphere 1.1 for OS/2). It's 
easy to port the changes back into the jsp.
4. I'm not too happy with using JavaMail for the mime- and 
multipart-{en|de}coding. It seemed like a good idea to use existing code, but its 
implementation is really too closely tied to e-mail. I had no luck finding a generic 
Mime toolkit. We might want to roll our own, which may support other 
mechanisms of encoding multiple parts than Mime Multipart for transport 
mechanisms which have support for this sort of thing already (not that I know of 
any).
5. With a bit more effort, batched requests consisting of multiple SOAP 
envelopes could be implemented too. The question there is how to distinguish 
SOAP Mime parts from other attachments with "text/xml" as a type. We could 
use the "Content-Disposition" header, setting the SOAP requests to "inline" and 
attachments to "attachment", for instance. Note that IMO the choice of "text/xml" 
in the SOAP spec was a very big mistake (SOAP request are *not* user 
readable documents!); it should've been "application/xml" with some new 
modifier for SOAP.
6. Unless if I'm mistaken, the marshall/unmarshall methods of the [de]serializers 
do not have access to any object holding some type of global context for the 
SOAP message. This makes it impossible to refer ahead, or store a reference 
to something that should be appended later. The value references in the SOAP 
spec, not yet supported in this implementation, would need something like this. 
Multipart Mime support is very similar.
I didn't feel like changing the syntax of the [un]marshall methods without public 
discussion, so I've implemented the following kludge... I've created an 
RPCContext class which holds a reference to the MimeMultipart object being 
built (serialisation) or referred to by the SOAP body (deserialisation). To obtain 
a reference to this object, it was equipped with a static Hashtable, mapping 
thread IDs to RPCContext objects, and static get/set methods to assign an 
RPCContext to the current running thread. This imposes the relatively light 
restriction on the client that only a single SOAP Call object can be built within the 
context of a thread, and it should be built in a single thread. The same applies to 
the server when it's unmarshalling the Call object or building the Response 
object. Though the single thread restriction can be circumvented the way I've 
implemented it, it remains a kludge.
I would like to propose that the structure be changed to add such an context 
object, accessible during envelope [un]marshalling. This context object could 
be the Envelope object perhaps. Other advantages than the ones discussed 
above are that the transport classes could use it to specify certain encoding 
preferences. E.g. smtp transport may want to impose a 7-bit restriction. Even the 
String serialiser may need that to encode Unicode characters in a special way. 
Also, the list of abilities of the partner could be specified here. E.g. if the 
MimeSerializer, invoked on the server, were to know that the client does not 
support multipart responses (e.g. because it did not indicate in a SOAP header 
that it does), it could inline an attachment as a string (JAF easily allows you to 
detect if this is possible) or a base-64 encoded byte array.

bfn, Wouter