Data Structures | Defines | Enumerations | Functions | Variables

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...

Defines

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

Enumerations

enum  { msg_multipart_hash }

Functions

msg_multipart_tmsg_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_tmsg_multipart_dup (su_home_t *home, msg_multipart_t const *header)
 Duplicate (deep copy) msg_multipart_t.
msg_multipart_tmsg_multipart_copy (su_home_t *home, msg_multipart_t const *header)
 Copy an msg_multipart_t header structure.
msg_multipart_tmsg_multipart_make (su_home_t *home, char const *s)
 Make a header structure msg_multipart_t.
msg_multipart_tmsg_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
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 ...
    }

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;
   }

Define Documentation

#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;

Enumeration Type Documentation

anonymous enum
Enumerator:
msg_multipart_hash 

Hash of Recursive multipart header.


Function Documentation

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_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);
Returns:
The function msg_multipart_copy() returns a pointer to newly copied header structure, or NULL upon an error.
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);
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_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_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);
Parameters:
x pointer to msg_multipart_t structure
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.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

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