Loading...
Searching...
No Matches
MIME Multipart Body
MIME Headers

Representing MIME multipart bodies and their manipulation. More...

## Data Structures

struct | msg_multipart_s
| Structure for a part in MIME multipart message. More...

## Macros

#define | MSG_MULTIPART_INIT()
| Header class for Recursive multipart header.

## Enumerations

enum | { msg_multipart_hash }

## Functions

msg_multipart_t * | msg_multipart_init (msg_multipart_t x[1])
| Initialize an msg_multipart_t structure.
int | msg_is_multipart (msg_header_t const *header)
| Test if header object is an instance of msg_multipart_t.
msg_multipart_t * | msg_multipart_dup (su_home_t *home, msg_multipart_t const *header)
| Duplicate (deep copy) msg_multipart_t.
msg_multipart_t * | msg_multipart_copy (su_home_t *home, msg_multipart_t const *header)
| Copy an msg_multipart_t header structure.
msg_multipart_t * | msg_multipart_make (su_home_t *home, char const *s)
| Make a header structure msg_multipart_t.
msg_multipart_t * | msg_multipart_format (su_home_t *home, char const *fmt,...)))
| Make a Recursive multipart header from formatting result.

## Variables

msg_parse_f | msg_multipart_d
| Parse a Recursive multipart header.
msg_print_f | msg_multipart_e
| Print a Recursive multipart header.

## Detailed Description

Representing MIME multipart bodies and their manipulation.

The msg_multipart_t is an object for storing MIME multipart message bodies. It includes message components used for framing and identifying message parts. Its syntax is defined in RFC 2046 as follows:

multipart-body := [preamble CRLF]
dash-boundary transport-padding CRLF
body-part *encapsulation
close-delimiter transport-padding
[CRLF epilogue]
preamble := discard-text
discard-text := *(*text CRLF)
; May be ignored or discarded.
dash-boundary := "--" boundary
; boundary taken from the value of boundary parameter
; of the Content-Type field.
boundary := 0*69<bchars> bcharsnospace
bchars := bcharsnospace / " "
bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
"+" / "_" / "," / "-" / "." /
"/" / ":" / "=" / "?"
transport-padding := *LWSP-char
; Composers MUST NOT generate non-zero length
; transport padding, but receivers MUST be able to
; handle padding added by message transports.
body-part := <"message" as defined in @RFC822, with all header fields
optional, not starting with the specified dash-boundary,
and with the delimiter not occurring anywhere in the body
part. Note that the semantics of a part differ from the
semantics of a message, as described in the text.>
encapsulation := delimiter transport-padding CRLF
body-part
close-delimiter := delimiter "--"
delimiter := CRLF dash-boundary
epilogue := discard-text
Type
struct node Type

Parsing a Multipart Message

When a message body contains a multipart entity (in other words, it has a MIME media type of "multipart"), the application can split the multipart entity into body parts

The parsing is relatively simple, the application just gives a memory home object, a Content-Type header object and message body object as an argument to msg_multipart_parse() function:

if (sip->sip_content_type &&
su_casenmatch(sip->sip_content_type, "multipart/", 10)) {
msg_multipart_t *mp;
if (sip->sip_multipart)
mp = sip->sip_multipart;
else
mp = msg_multipart_parse(msg_home(msg),
sip->sip_content_type,
(sip_payload_t *)sip->sip_payload);
if (mp)
... processing multipart ...
else
... error handling ...
}
sip_payload_t
msg_payload_t sip_payload_t
msg_home
#define msg_home(h)
Cast a msg_t pointer to a su_home_t pointer.
Definition msg.h:82
msg_multipart_parse
msg_multipart_t * msg_multipart_parse(su_home_t *home, msg_content_type_t const *c, msg_payload_t *pl)
Parse a MIME multipart.
Definition msg_mime.c:368
msg_multipart_t
struct msg_multipart_s msg_multipart_t
Multipart body object.
Definition msg_mime.h:74
su_casenmatch
int su_casenmatch(char const *s1, char const *with, size_t n)

The resulting list of msg_multipart_t structures contain the parts of the multipart entity, each part represented by a separate msg_multipart_t structure. Please note that in order to make error recovery possible, the parsing is not recursive - if multipart contains another multipart, the application is responsible for scanning for it and parsing it.

Constructing a Multipart Message

Constructing a multipart body is a bit more hairy. The application needs a message object (msg_t), which is used to buffer the encoding of multipart components.

As an example, let us create a "multipart/mixed" multipart entity with a HTML and GIF contents, and convert it into a sip_payload_t structure:

msg_t *msg = msg_create(sip_default_mclass, 0);
su_home_t *home = msg_home(msg);
sip_t *sip = sip_object(msg);
sip_content_type_t *c;
msg_multipart_t *mp = NULL;
msg_header_t *h = NULL;
char *b;
size_t len, offset;
mp = msg_multipart_create(home, "text/html;level=3", html, strlen(html));
mp->mp_next = msg_multipart_create(home, "image/gif", gif, giflen);
c = sip_content_type_make(home, "multipart/mixed");
// Add delimiters to multipart, and boundary parameter to content-type
if (msg_multipart_complete(home, c, mp) < 0)
return -1; // Error
// Combine multipart components into the chain
h = NULL;
if (msg_multipart_serialize(&h, mp) < 0)
return -1; // Error
// Encode all multipart components
len = msg_multipart_prepare(msg, mp, 0);
if (len < 0)
return -1; // Error
pl = sip_payload_create(home, NULL, len);
// Copy each element from multipart to pl_data
b = pl->pl_data;
for (offset = 0, h = mp; offset < len; h = h->sh_succ) {
memcpy(b + offset, h->sh_data, h->sh_len);
offset += h->sh_len;
}
sip_content_type_t
struct msg_content_type_s sip_content_type_t
sip_content_type_make
sip_content_type_t * sip_content_type_make(su_home_t *home, char const *s))
sip_payload_create
sip_payload_t * sip_payload_create(su_home_t *, void const *data, isize_t len)
msg_create
msg_t * msg_create(msg_mclass_t const *mc, int flags)
Create a message.
Definition msg.c:100
msg_multipart_prepare
issize_t msg_multipart_prepare(msg_t *msg, msg_multipart_t *mp, int flags)
Encode a multipart.
Definition msg_mime.c:817
msg_multipart_complete
int msg_multipart_complete(su_home_t *home, msg_content_type_t *c, msg_multipart_t *mp)
Add all missing parts to the multipart.
Definition msg_mime.c:575
msg_multipart_serialize
msg_header_t * msg_multipart_serialize(msg_header_t **head0, msg_multipart_t *mp)
Serialize a multipart message.
Definition msg_mime.c:687
msg_multipart_create
msg_multipart_t * msg_multipart_create(su_home_t *home, char const *content_type, void const *data, isize_t dlen)
Create a part for MIME multipart entity.
Definition msg_mime.c:235
msg_header_t
MSG_HDR_T msg_header_t
Any protocol-specific header object.
Definition msg_types.h:87
msg_t
struct msg_s msg_t
Message object.
Definition msg_types.h:54
sip_t
struct sip_s sip_t
sip_default_mclass
msg_mclass_t const * sip_default_mclass(void)
sip_object
sip_t * sip_object(msg_t const *msg)
msg_multipart_s::mp_next
msg_multipart_t * mp_next
Next part in multipart body.
Definition msg_mime.h:162
su_home_t
SU_HOME_T su_home_t

## Macro Definition Documentation

## MSG_MULTIPART_INIT

#define MSG_MULTIPART_INIT | ( |  | ) |

Header class for Recursive multipart header.

The header class msg_multipart_class defines how a Recursive multipart header header is parsed and printed. It also contains methods used by message parser and other functions to manipulate the msg_multipart_t header structure. Initializer for an msg_multipart_t structure.

A static msg_multipart_t structure must be initialized with the MSG_MULTIPART_INIT() macro. For instance,

msg_multipart_t msg_multipart = MSG_MULTIPART_INIT;
MSG_MULTIPART_INIT
#define MSG_MULTIPART_INIT()
Header class for Recursive multipart header.
Definition msg_mime_protos.h:3602

## Enumeration Type Documentation

## anonymous enum

anonymous enum

Enumerator
msg_multipart_hash | Hash of Recursive multipart header.

## Function Documentation

## msg_is_multipart()

int msg_is_multipart | ( | msg_header_t const * | header | ) |

inline

Test if header object is an instance of msg_multipart_t.

The function msg_is_multipart() returns true (nonzero) if the header class is an instance of Recursive multipart header object and false (zero) otherwise.

Parameters

  header | pointer to the header structure to be tested

Returns
  The function msg_is_multipart() returns true (nonzero) if the header object is an instance of header Recursive multipart header and false (zero) otherwise.

## msg_multipart_copy()

msg_multipart_t * msg_multipart_copy | ( | su_home_t * | home,
|  | msg_multipart_t const * | header )

inline

Copy an msg_multipart_t header structure.

The function msg_multipart_copy() copies a header structure header. If the header structure header contains a reference (`header->h_next`) to a list of headers, all the headers in that list are copied, too. The function uses given memory home to allocate all the memory areas used to copy the header structure header.

Parameters

  home | memory home used to allocate new structure
  header | pointer to the header structure to be duplicated

When copying, only the header structure and parameter lists attached to it are duplicated. The new header structure retains all the references to the strings within the old header, including the encoding of the old header, if present.

Example
  multipart = msg_multipart_copy(home, msg->msg_multipart);
  msg_multipart_copy
  msg_multipart_t * msg_multipart_copy(su_home_t *home, msg_multipart_t const *header)
  Copy an msg_multipart_t header structure.
  Definition msg_mime_protos.h:3731

Returns
  The function msg_multipart_copy() returns a pointer to newly copied header structure, or NULL upon an error.

## msg_multipart_dup()

msg_multipart_t * msg_multipart_dup | ( | su_home_t * | home,
|  | msg_multipart_t const * | header )

inline

Duplicate (deep copy) msg_multipart_t.

The function msg_multipart_dup() duplicates a header structure header. If the header structure header contains a reference (`header->x_next`) to a list of headers, all the headers in the list are duplicated, too.

Parameters

  home | memory home used to allocate new structure
  header | header structure to be duplicated

When duplicating, all parameter lists and non-constant strings attached to the header are copied, too. The function uses given memory home to allocate all the memory areas used to copy the header.

Example
  multipart = msg_multipart_dup(home, msg->msg_multipart);
  msg_multipart_dup
  msg_multipart_t * msg_multipart_dup(su_home_t *home, msg_multipart_t const *header)
  Duplicate (deep copy) msg_multipart_t.
  Definition msg_mime_protos.h:3686

Returns
  The function msg_multipart_dup() returns a pointer to the newly duplicated msg_multipart_t header structure, or NULL upon an error.

## msg_multipart_format()

msg_multipart_t * msg_multipart_format | ( | su_home_t * | home,
|  | char const * | fmt,
|  |  | ... )

inline

Make a Recursive multipart header from formatting result.

The function msg_multipart_format() makes a new Recursive multipart header object using snprintf-formatted result as its value. The function first prints the arguments according to the format fmt specified. Then it allocates a new header structure, and uses the formatting result as the header value.

Parameters

  home | memory home used to allocate new header structure.
  fmt | string used as a printf()-style format
  ... | argument list for format

Note
  This function may be implemented as a macro calling msg_header_format().

Returns
  The function msg_multipart_format() returns a pointer to newly makes header structure, or NULL upon an error.

## msg_multipart_init()

msg_multipart_t * msg_multipart_init | ( | msg_multipart_t | x[1] | ) |

inline

Initialize an msg_multipart_t structure.

An msg_multipart_t structure can be initialized with the msg_multipart_init() function/macro. For instance,

msg_multipart_t msg_multipart;
msg_multipart_init(&msg_multipart);
msg_multipart_init
msg_multipart_t * msg_multipart_init(msg_multipart_t x[1])
Initialize an msg_multipart_t structure.
Definition msg_mime_protos.h:3619

Parameters

  x | pointer to msg_multipart_t structure

## msg_multipart_make()

msg_multipart_t * msg_multipart_make | ( | su_home_t * | home,
|  | char const * | s )

inline

Make a header structure msg_multipart_t.

The function msg_multipart_make() makes a new msg_multipart_t header structure. It allocates a new header structure, and decodes the string s as the value of the structure.

Parameters

  home | memory home used to allocate new header structure.
  s | string to be decoded as value of the new header structure

Note
  This function may be implemented as a macro calling msg_header_make().

Returns
  The function msg_multipart_make() returns a pointer to newly maked msg_multipart_t header structure, or NULL upon an error.

Sofia-SIP 1.12.11devel - Copyright (C) 2006 Nokia Corporation. All rights reserved. Licensed under the terms of the GNU Lesser General Public License.