msg 1.12.11devel
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
MIME Multipart Body

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_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
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)) {
if (sip->sip_multipart)
mp = sip->sip_multipart;
else
sip->sip_content_type,
(sip_payload_t *)sip->sip_payload);
if (mp)
... processing multipart ...
else
... error handling ...
}
#define msg_home(h)
Cast a msg_t pointer to a su_home_t pointer.
Definition msg.h:82
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
Structure for a part in MIME multipart message.
Definition msg_mime.h:160
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 * sip_content_type_make(su_home_t *home, char const *s))
sip_payload_t * sip_payload_create(su_home_t *, void const *data, isize_t len)
msg_t * msg_create(msg_mclass_t const *mc, int flags)
Create a message.
Definition msg.c:100
issize_t msg_multipart_prepare(msg_t *msg, msg_multipart_t *mp, int flags)
Encode a multipart.
Definition msg_mime.c:817
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_header_t * msg_multipart_serialize(msg_header_t **head0, msg_multipart_t *mp)
Serialize a multipart message.
Definition msg_mime.c:687
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_HDR_T msg_header_t
Any protocol-specific header object.
Definition msg_types.h:87
sip_t * sip_object(msg_t const *msg)
msg_multipart_t * mp_next
Next part in multipart body.
Definition msg_mime.h:162
Message object.
Definition msg_internal.h:59
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,

#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
headerpointer 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
homememory home used to allocate new structure
headerpointer 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_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
homememory home used to allocate new structure
headerheader 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_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
homememory home used to allocate new header structure.
fmtstring 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_t * msg_multipart_init(msg_multipart_t x[1])
Initialize an msg_multipart_t structure.
Definition msg_mime_protos.h:3619
Parameters
xpointer 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
homememory home used to allocate new header structure.
sstring 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.