17.1.19.DIME encapsulation of SOAP messages

The Direct Message Encapsulation (DiME) format is a message format that can be used to encapsulate one or more payloads of arbitrary type and size. This format can be used in place of MIME, but benefits of DIME are ease of parsing and low memory consumption, as DIME does not require loading the whole message body in order to parse it. This is due to the fact that MIME does not have mechanism for specifying the length of payloads etc. DIME prefixes all data with length and type information.

The structure of a DIME message as per draft-nielsen-dime-02 is:

/*
      Legend:

      VERSION = 0x01
      RESRVD  = 0x00
      MB - begin mark
      ME - end mark
      CF - chunked flag
      TYPE_T - type of content type field

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |         |M|M|C|       |       |                               |
     | VERSION |B|E|F| TYPE_T| RESRVD|         OPTIONS_LENGTH        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |            ID_LENGTH          |           TYPE_LENGTH         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                          DATA_LENGTH                          |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                     OPTIONS + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                          ID + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                        TYPE + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                        DATA + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
   

The MB,ME,CF flags are used to indicate which part of the DIME message is the current block of data. Also, we notice that there are four length fields of fixed length before any data, id or type payload. This is to make the payload easier to read.

The Virtuoso server implements a DIME parser and composer as functions and filter for DIME in SOAP server. Furthermore the Virtuoso WSDL generator can be instructed to specify a DIME extension to the PL procedure exposed as SOAP method. The implementation is based on draft-nielsen-dime-02 RFC proposal. Please note that in the rest of document we will use 'DIME attachment' term , which is about SOAP message with attachment encapsulated with DIME as per draft-nielsen-dime-soap-01. The special case in these messages is type of first payload, so it's supposed to be a SOAP:Envelope message.

Note: Option fields are not supported.

To setup a SOAP endpoint to recognize DIME encapsulation the "DIME-ENC" option to SOAP in virtual directory must be set to 'yes'. Furthermore the WSDL description of endpoint defined as DIME enabled will contain WSDL extensions to DIME.

As not in all cases input and output of the SOAP server needs to be DIME encoded, the particular PL procedure exposed as SOAP method needs to be defined in special way to indicate which traffic is encoded as DIME. This is done by using special keywords on procedure declaration:

   CREATE PROCEDURE ([PARAMETERS DECLARATION])
    [RETURNS TYPE] [(__SOAP_TYPE|__SOAP_DOC|_SOAP_DOCW) 'LITERAL'] [__SOAP_DIME_ENC (IN/OUT/INOUT)]
   

The '__SOAP_DIME_ENC IN' indicate that the procedure expects a DIME attachments on input. This can also be used with OUT and INOUT. This will also be indicated in WSDL file (services.wsdl) as DIME extension in appropriate place of 'soap:operation' element.

The format of SOAP attachments passed to PL procedure defined in this way is an array which consists of three string elements: ID, content-type, and attachment data itself. The same format must be used when parameter is an output which needs to be sent as DIME attachment. There is also a special parameter of PL procedure exposed as SOAP method named 'ws_soap_attachments', so when we have such, all attachments received will be passed thru it. In practice we will not need to use 'ws_soap_attachments' , but anyway it's practical use is to handle unreferenced parameters or to debug the request.

Finally we must say that type of parameter needs to have datatype declared as per 'WSDL Extension for SOAP in DIME' proposal, this is needed for indicating in the WSDL what to expect and how to send the attachment. See also the example below.

Example17.23.Using DIME encapsulation

Suppose we need to accept a binary attachment and echo it back as string encoded in the popular 'base64'.

We first need to enable DIME encapsulation to an endpoint, with virtual directory definition:

SQL> VHOST_DEFINE (lpath=>'/r4/groupG/dime/rpc', ppath=>'/SOAP/', soap_user=>'interop4',
    soap_opts => vector ('DIME-ENC', 'yes')) ;

The sample PL procedure that takes a binary attachment and transforms it to a base64 encoded string must be declared as:

create procedure
EchoAttachmentAsBase64 (in "In" nvarchar __soap_type 'http://soapinterop.org/attachments/xsd:ReferencedBinary')
returns nvarchar __soap_type 'base64Binary'
__soap_dime_enc in
{
  -- we are getting the attachment as the 3rd element of input,
  -- do the base64 encoding for it and return it to the requestor
  return encode_base64 (cast ("In"[2] as varchar));
}
;

As we have noticed an 'ReferencedBinary' is used to declare 'In' parameter. This has a special purpose for WSDL definition, not for SOAP processing itself. In that case clients are instructed to look at annotation/appinfo of a simple type declared as:

        <complexType name="ReferencedBinary">
                <simpleContent>
                        <restriction base="soap-enc:base64Binary">
                                <annotation>
                                        <appinfo>
                                                <content:mediaType value="application/octetstream"/>
                                        </appinfo>
                                </annotation>
                                <attributeGroup ref="soap-enc:commonAttributes"/>
                        </restriction>
                </simpleContent>
        </complexType>

This is a little-bit tricky, but this is how to indicate the type of the content and how to resolve the references to the attachments as per the WSDL Extension for SOAP in DIME' proposal.