Using MTOM for Attachments
You can include attachments in SOAP request and response messages. The preferred way to do this is to use InterSystems IRIS® data platform support for MTOM (Message Transmission Optimization Mechanism).
You can also specify MTOM use within a policy; see Securing Web Services.
You can also configure InterSystems IRIS® data platform web services and web clients to use gzip to compress their messages after performing any packaging; see Fine-Tuning a Web Service in InterSystems IRIS and Fine-Tuning a Web Client in InterSystems IRIS.
Attachments and SOAP Message Packaging
Attachments are generally used to carry binary data. InterSystems IRIS SOAP support provides three ways to package your SOAP messages. Before discussing detailed options, it is worthwhile to review these kinds of packaging.
-
Package the message with all parts inline (without attachments). Use base-64 encoding for any binary data.
This is the default behavior of InterSystems IRIS web services and web clients, except when a web service receives an MTOM request (in which case, the service responds with an MTOM response).
-
Package the message according to the MTOM (Message Transmission Optimization Mechanism) specification, which results in a slightly more compact message than an all-inline message. This is now the preferred approach for SOAP messages.
When you use this technique, the system automatically packages the SOAP messages appropriately. That is, the MIME parts are created as needed and are added to the message without your intervention.
Also by default, when InterSystems IRIS creates an MTOM package, it outputs binary streams using an attachment, and it outputs binary strings (%BinaryOpens in a new tab or %xsd.base64BinaryOpens in a new tab) inline; you can control this behavior.
For links to the specifications for MTOM, see SOAP Standards.
-
Package the message according to the SOAP with Attachments specification, which results in a slightly more compact message than an all-inline message.
When you use this technique, you must manually create MIME parts, populate them with data, specify the MIME headers as appropriate, and attach the parts to the SOAP message. This usually requires more work than the MTOM technique. See Using SOAP with Attachments.
SOAP Messages with All-Inline Parts (Default)
The default way to package a SOAP message is to include all its elements as inline parts (that is, without attachments). Any binary data is included inline as base-64–encoded data. For example (with line breaks and spaces added for readability):
HTTP/1.1 200 OK
Date: Wed, 19 Nov 2008 21:57:50 GMT
Server: Apache
SET-COOKIE: CSPSESSIONID-SP-8080-UP-csp-gsoap-=003000010000248
guobl000000K7opwlDlY$XbvrGR1eYZsA--; path=/csp/mysamples/;
CACHE-CONTROL: no-cache
EXPIRES: Thu, 29 Oct 1998 17:04:19 GMT
PRAGMA: no-cache
TRANSFER-ENCODING: chunked
Connection: close
Content-Type: text/xml; charset=UTF-8
1d7b
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='https://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xmlns:s='https://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body>
<DownloadResponse xmlns="https://www.filetransfer.org">
<DownloadResult><Filename>sample.pdf</Filename>
<IsBinary>true</IsBinary>
<BinaryContents>
[very long binary content not shown here]
</BinaryContents></attachment></Upload>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Notice that this packaging does not use MIME, and there are no message boundaries.
SOAP Messages with MTOM Packaging
Another way to package a SOAP message is to use MIME parts as described in the MTOM (Message Transmission Optimization Mechanism) specification. Binary data can be placed into separate MIME parts without base-64 encoding. The SOAP message includes references to the separate parts as needed. For example (with line breaks and spaces added for readability):
HTTP/1.1 200 OK
Date: Wed, 19 Nov 2008 21:54:57 GMT
Server: Apache
SET-COOKIE: CSPSESSIONID-SP-8080-UP-csp-gsoap-=003000010
000247guhlx000000NW1KN5UtWg$CWY38$bbTOQ--; path=/csp/mysamples/;
CACHE-CONTROL: no-cache
EXPIRES: Thu, 29 Oct 1998 17:04:19 GMT
MIME-VERSION: 1.0
PRAGMA: no-cache
TRANSFER-ENCODING: chunked
Connection: close
Content-Type: multipart/related; type="application/xop+xml";
boundary=--boundary388.5294117647058824932.470588235294118--;
start="<0.B1150656.EC8A.4B5A.8835.A932E318190B>"; start-info="text/xml"
1ddb
----boundary388.5294117647058824932.470588235294118--
Content-Type: application/xop+xml; type="text/xml"; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Content-Id: <0.B1150656.EC8A.4B5A.8835.A932E318190B>
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='https://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xmlns:s='https://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body>
<DownloadResponse xmlns="https://www.filetransfer.org">
<DownloadResult>
<Filename>sample.pdf</Filename>
<IsBinary>true</IsBinary>
<BinaryContents>
<xop:Include href="cid:1.B1150656.EC8A.4B5A.8835.A932E318190B"
xmlns:xop="https://www.w3.org/2004/08/xop/include"/>
</BinaryContents></DownloadResult></DownloadResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
----boundary388.5294117647058824932.470588235294118--
Content-Id: <1.B1150656.EC8A.4B5A.8835.A932E318190B>
Content-Transfer-Encoding: binary
CONTENT-TYPE: application/octet-stream
[very long binary content not shown here]
Notice the following differences compared to the default package:
-
The message has MIME parts and thus includes boundaries.
-
The MIME part has a Content-ID attribute.
-
In the SOAP body, the element BinaryContents consists of a reference to that content ID.
SOAP with Attachments
A third way to package SOAP messages is to use the SOAP with Attachments specification, which also uses MIME parts, but packages the message somewhat differently from MTOM. An example follows (with line breaks and spaces added for readability):
HTTP/1.1 200 OK
Date: Mon, 09 Nov 2009 17:47:36 GMT
Server: Apache
SET-COOKIE: CSPSESSIONID-SP-8080-UP-csp-gsoap-=
000000010000213eMwn70000004swjTo4cGuInLMU1n7jaPg--; path=/csp/mysamples/;
CACHE-CONTROL: no-cache
EXPIRES: Thu, 29 Oct 1998 17:04:19 GMT
MIME-VERSION: 1.0
PRAGMA: no-cache
TRANSFER-ENCODING: chunked
Connection: close
Content-Type: multipart/related; type="text/xml";
boundary=--boundary2629.3529411764705883531.411764705882353--
1ca2
----boundary2629.3529411764705883531.411764705882353--
Content-Type: text/xml; charset="UTF-8"
Content-Transfer-Encoding: 8bit
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='https://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xmlns:s='https://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body><DownloadBinaryResponse xmlns="https://www.filetransfer.org">
<DownloadBinaryResult>MQ==</DownloadBinaryResult></DownloadBinaryResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
----boundary2629.3529411764705883531.411764705882353--
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
%PDF-1.4
%âãÏÓ
86 0 obj
<</Length 87 0 R
/Filter /FlateDecode
>>
stream
[stream not shown]
As with MTOM, there is a boundary string and the attachment is a MIME part. However, in contrast to MTOM, the MIME part does not have a content ID, and the SOAP body does not include any references to the MIME part.
Default Behavior of InterSystems IRIS Web Services and Web Clients
By default, an InterSystems IRIS web service behaves as follows:
-
If it receives a request in an MTOM package, the web service sends the response as an MTOM package.
Also, the IsMTOM property of the web service instance is set to 1.
-
If it receives a request not in an MTOM package, the web service sends the response not in an MTOM package.
By default, an InterSystems IRIS web client behaves as follows:
-
It does not send requests as MTOM packages.
-
It processes the response regardless of whether the response is in an MTOM package.
If the response is in an MTOM package, the IsMTOM property of the web client instance is set to 1. If the response is not in an MTOM package, the IsMTOM property is not changed.
Forcing Responses as MTOM Packages
You can force an InterSystems IRIS web service to send every response as an MTOM package. To do, do any of the following:
-
In your InterSystems IRIS web service class, set the MTOMREQUIRED parameter to 1.
-
In your InterSystems IRIS web service instance, set the MTOMRequired property to 1. You can do this within the web method or within the OnPreWebMethod() callback. For an introduction to this callback, see Customizing Callbacks of the Web Service.
-
Attach a policy statement for the web service to send MTOM packages. To do so, you create and compile a configuration class that refers to the web service class; in this policy, enable use of MTOM. See Securing Web Services.
If you attach such a policy statement, your values for MTOMREQUIRED is ignored, and MTOMRequired is set equal to 1.
Effect on the WSDL
MTOMREQUIRED and MTOMRequired do not affect the WSDL of the web service.
A policy statement that refers to MTOM does affect the WSDL; if you add a policy statement, it is necessary to regenerate any web clients. For an InterSystems IRIS web client, you can simply attach an MTOM policy statement to the client instead of regenerating the client classes.
Forcing Requests as MTOM Packages
You can force an InterSystems IRIS web client to send every request as an MTOM package. To do, do either of the following:
-
In your InterSystems IRIS web client class, set the MTOMREQUIRED parameter to 1.
-
In your InterSystems IRIS web client instance, set the MTOMRequired property to 1.
-
Attach a policy statement to the web client to send MTOM packages. To do so, you create and compile a configuration class that refers to the web service client; in this policy, enable use of MTOM. See Securing Web Services.
If you attach such a policy statement, your values for MTOMREQUIRED is ignored, and MTOMRequired is set equal to 1.
Effect on the WSDL
MTOMREQUIRED and MTOMRequired do not assume any change in the WSDL of the web service used by this web client.
A policy statement that refers to MTOM does affect the WSDL. That is, you would add an MTOM policy statement to a client only if the web service required it.
Controlling the MTOM Packaging
By default, when InterSystems IRIS creates an MTOM package, it uses the following rules:
-
It outputs binary strings (%BinaryOpens in a new tab or %xsd.base64BinaryOpens in a new tab) inline.
-
It outputs binary streams using an attachment.
You can use the MTOM property parameter to change this default:
-
1 means output this property as an attachment.
-
0 means output this property inline.
The MTOM property parameter has no effect when a web service or web client is not using MTOM.
Also, this property parameter has no effect on the WSDL of a web service.
Example
This example shows an InterSystems IRIS web service that receives a binary file and sends it back to the caller.
The corresponding web client sends a file with a hardcoded filename, receives the same file from the web service, and then saves it with a new name to prove that it has been successfully sent.
Web Service
The web service is as follows:
/// Receive an attachment and send it back
Class MTOM.RoundTripWS Extends %SOAP.WebService
{
/// Name of the web service.
Parameter SERVICENAME = "RoundTrip";
/// SOAP namespace for the web service
Parameter NAMESPACE = "https://www.roundtrip.org";
/// Receive an attachment and send it back
Method ReceiveFile(attachment As %GlobalBinaryStream) As %GlobalBinaryStream [ WebMethod ]
{
Set ..MTOMRequired=1
Quit attachment
}
}
Web Client
The generated web client (MTOMClient.RoundTripSoap) contains the method ReceiveFile(), which invokes the web method of the same name. This method is originally as follows:
Method ReceiveFile(attachment As %xsd.base64Binary) As %xsd.base64Binary
[ Final, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
Quit ..WebMethod("ReceiveFile").Invoke($this,"https://www.roundtrip.org/MTOM.RoundTripWS.ReceiveFile",
.attachment)
}
Because the files we send might exceed the string length limit, we adjust the method signature as follows:
Method ReceiveFile(attachment As %GlobalBinaryStream) As %GlobalBinaryStream
[ Final, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
Quit ..WebMethod("ReceiveFile").Invoke($this,"https://www.roundtrip.org/MTOM.RoundTripWS.ReceiveFile",
.attachment)
}
MTOM is not required by default in the web client; that is, the MTOMREQUIRED parameter is not defined.
To use this proxy client, we create the following class:
Include %systemInclude
Class MTOMClient.UseClient
{
/// For this example, hardcode what we are sending
ClassMethod SendFile() As %GlobalBinaryStream
{
Set client=##class(MTOMClient.RoundTripSoap).%New()
Set client.MTOMRequired=1
//reset location to port 8080 to enable tracing
Set client.Location="https://devsys:8080/csp/mysamples/MTOM.RoundTripWS.cls"
//create file
Set filename="c:\sample.pdf"
Set file=##class(%Library.FileBinaryStream).%New()
Set file.Filename=filename
//create %GlobalBinaryStream
Set attachment=##class(%GlobalBinaryStream).%New()
Do attachment.CopyFrom(file)
//call the web service
Set answer=client.ReceiveFile(attachment)
//save the received file to prove we made the round trip successfully
Set newfilename="c:\roundtrip"_$h_"sample.pdf"
Set newfile=##class(%Library.FileBinaryStream).%New()
Set newfile.Filename=newfilename
Do newfile.CopyFromAndSave(answer)
Quit answer
}
}