|  | Home | Documentation | DIME attachment functions updated Sat Dec 23 2023 by Robert van Engelen |

- Main Page
- Modules
- Classes
- Files

Classes | Functions
DIME attachment functions

This module defines functions to set and get DIME attachments. More...

## Classes
struct | xsd__base64Binary
| XSD base64Binary structure with attachment data. More...
struct | _xop__Include
| XOP include structure with attachment data. More...
struct | xsd__hexBinary
| XSD hexBinary structure with attachment data. More...
struct | soap_dime
| Stores a linked list of DIME attachments received. More...

## Functions
int | soap_set_dime (struct soap *soap)
| Enable DIME attachments. More...
void | soap_clr_dime (struct soap *soap)
| Disable DIME attachments. More...
int | soap_set_dime_attachment (struct soap *soap, const char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option)
| Add a DIME attachment to the SOAP/XML message. More...
char * | soap_dime_option (struct soap *soap, unsigned short optype, const char *option)
| Creates a DIME option. More...

## Detailed Description

This module defines functions to set and get DIME attachments.

For more information on the DIME protocol, see for example https://msdn.microsoft.com/en-us/library/aa480488.aspx

There are two ways to add DIME attachments to SOAP/XML messages for sending:

- use `soap_set_dime_attachment` to explicitly add an attachment that contains the specified source of data;
- use `xsd__base64Binary` or `_xop__Include` structures in the serializable data of a SOAP/XML message, where the specified data is serialized in DIME attachments automatically when one of the `id`, `type` or `options` member variables are non-NULL.

Both methods also support streaming DIME attachments to send using the `soap::fdimereadopen`, `soap::fdimeread`, and `soap::fdimereadclose` callbacks that fetch the data to send, where a user-defined handle should be specified for the `ptr` parameter of `soap_set_dime_attachment` or the `xsd__base64Binary::__ptr` member variable instead of a pointer to the actual data. This handle can be used by the callbacks to fetch the specific data to transmit.

Receiving DIME attachments attached to SOAP/XML messages is automatic. The DIME attachments are converted to binary data and stored in the `xsd__base64Binary` structures that reference the DIME attachments via the `xsd__base64Binary::id` string, meaning that the `xsd__base64Binary::__ptr` (points to the data) and `xsd__base64Binary::__size` (data length) are populated automatically with the DIME binary data. However, if the streaming DIME callbacks `soap::fdimewriteopen`, `soap::fdimewrite`, and `soap::fdimewriteclose` are defined then the attachments are streamed to these callbacks instead.

For example, to send and receive a SOAP/XML message with DIME attachments using a serializable `xsd__base64Binary` structure:

// example .h file for soapcpp2
//gsoap ns service name: example
//gsoap ns service namespace: urn:example
struct xsd__base64Binary {
unsigned char *__ptr; // pointer to binary data
int __size; // size of the binary data
char *id; // NULL to generate an id or assign this member variable a unique UUID
char *type; // MIME type of the data
char *options; // DIME options
};
int ns__webmethod(struct xsd__base64Binary *data, struct xsd__base64Binary *result);
// example client implementation based on the above example .h file for soapcpp2
#include "soapH.h"
int main()
{
struct soap *soap = soap_new();
struct xsd__base64Binary data, result;
data.__ptr = ...; // points to binary image data to send
data.__size = ...; // size of the image data to send
data.id = NULL; // this will be assigned by the engine
data.type = "image/jpg";
data.options = soap_dime_option(soap, 0, "Picture.png"); // DIME option 0 = "Picture.png" to store file name
if (soap_call_ns__webmethod(soap, endpoint, NULL, &data, &result))
soap_print_fault(soap, stderr);
else
... // success, use the result
soap_destroy(soap);
soap_end(soap);
soap_free(soap);
}
// example service implementation based on the above example .h file for soapcpp2
#include "soapH.h"
int main()
{
struct soap *soap = soap_new();
... // serve requests with soap_bind, soap_accept, soap_ssl_accept, and soap_serve
}
int ns__webmethod(struct soap *soap, struct xsd__base64Binary *data, struct xsd__base64Binary *result)
{
// echo back the structure (as a DIME attachment)
result->__ptr = data->__ptr;
result->__size = data->__size;
retult->id = data->id;
retult->type = data->type;
retult->options = data->options;
return SOAP_OK;
}

Besides receiving the attachments in `xsd__base64Binary` structures, on the receiving side you can also iterate over the DIME attachments received as follows:

#include "soapH.h"
int main()
{
struct soap *soap = soap_new();
... // call soap_call_ns__webmethod etc.
{
int n = 0;
struct soap_multipart *attachment;
for (attachment = soap->dime.list; attachment; attachment = attachment->next)
{
++n;
printf("Part %d:\n", n);
printf("ptr =%p\n", attachment->ptr);
printf("size =%ul\n", attachment->size);
printf("id =%s\n", attachment->id ? attachment->id : "");
printf("type =%s\n", attachment->type ? attachment->type : "");
// DIME options are formatted according to the DIME protocol
if (attachment->options)
{
// extract length of first option
size_t len = ((unsigned char)attachment->options[2] << 8) | ((unsigned char)attachment->options[3]);
// allocate and copy the first option, which is assumed to be a name
char *name = (char*)soap_malloc(soap, len + 1);
strncpy(name, attachment->options + 4, len);
name[len] = '\0';
printf("option=%s\n", name);
}
}
}
}

In C++ you can use an iterator for the last part of this example:

struct soap *soap = soap_new();
... // call soap_call_ns__webmethod etc.
int n = 0;
for (soap_multipart::iterator i = soap->dime.begin(); i != soap->dime.end(); ++i)
{
++n;
printf("Part %d:\n", n);
printf("ptr =%p\n", i->ptr);
... // etc
}

At the server side the code to retrieve the DIME attachments is the same.

## Function Documentation

void soap_clr_dime | ( | struct soap * | soap | ) |

Disable DIME attachments.

This function disables DIME attachments, unless the data to serialize as an XML message contains attachments defined by `xsd__base64Binary` and `_xop__Include` structures.

char* soap_dime_option | ( | struct soap * | soap,
|  | unsigned short | optype,
|  | const char * | option
| ) |  |

Creates a DIME option.

This function creates a DIME option-formatted string for the `xsd__base64Binary::options` member variable or `_xop__Include::options` member variable.

Returns
  a DIME option-formatted string

Parameters

  soap | `soap` context
  optype | a 16 bit DIME option type
  option | one DIME option as a text string

int soap_set_dime | ( | struct soap * | soap | ) |

Enable DIME attachments.

This function enables sending DIME attachments. This function is generally not required because DIME attachments are automatically detected as `xsd__base64Binary` and `_xop__Include` structures in the data to serialize as an XML message with the attachments automatically added or DIME attachments can be explicitly added with `soap_set_dime_attachment`.

int soap_set_dime_attachment | ( | struct soap * | soap,
|  | const char * | ptr,
|  | size_t | size,
|  | const char * | type,
|  | const char * | id,
|  | unsigned short | optype,
|  | const char * | option
| ) |  |

Add a DIME attachment to the SOAP/XML message.

This function adds a DIME attachment to the XML message to send. The specified `ptr` points to the data to send of length specified by `size`. The `type` parameter indicates the MIME type of the data or can be NULL. The `id` parameter uniquely identifies the attachment in the message, which can be omitted by specifying NULL. The `option` parameter is an option such as a description of the data and `optype` is a user-defined option type (as per DIME option specification format). The `ptr` parameter must be persistent. The `ptr` parameter passed to this function must be persistent in memory until the attachment was sent. Returns `SOAP_OK` or a `soap_status` error code.

When streaming DIME attachments are enabled by defining the `soap::fdimereadopen`, `soap::fdimeread`, `soap::fdimereadclose` then the `ptr` parameter should point to a user-defined structure that is passed to `soap::fdimereadopen` as the `handle` parameter.

Example:

#include "soapH.h"
struct soap *soap = soap_new1(SOAP_IO_CHUNK);
const char *data = ...; // points to data to send
size_t size = ...; // length of the data
soap->connect_timeout = 30; // 30 seconds max connect stall time
soap->send_timeout = soap_recv_timeout = 5; // 5 seconds max socket stall time (unlimited by default)
soap->transfer_timeout = 30; // 30 seconds max message transfer time (unlimited by default)
soap->recv_maxlength = 1048576; // limit messages received to 1MB (2GB by default)
soap_set_dime_attachment(soap, data, size, "image/jpg", NULL, 0, "Picture");
if (soap_call_ns__webmethod(soap, endpoint, NULL, ...))
{
soap_print_fault(soap, stderr);
if (soap->errnum == 0) // timed out, exit program
exit(EXIT_FAILURE);
}
else
{
... // success
}
soap_destroy(soap);
soap_end(soap);
soap_free(soap);

See also
  `xsd__base64Binary`, `_xop__Include`, `soap_rand_uuid`, `soap::fdimereadopen`, `soap::fdimeread`, `soap::fdimereadclose`.

Returns
  `SOAP_OK` or a `soap_status` error code

Parameters

  soap | `soap` context
  ptr | pointer to data
  size | length of the data
  type | MIME type of the data or NULL
  id | content ID of the data or NULL
  optype | a 16 bit DIME option type
  option | one DIME option as a text string or NULL