Skip to main content
Previous sectionNext section

Creating, Writing, and Reading MIME Messages

Caché provides a class that you can use to create multipart MIME messages (%Net.MIMEPart). You use this class when you create attachments to add to SOAP messages; see Creating Web Services and Web Clients in Caché. Because MIME is a common standard, there are many other possible applications, such as email processing and HTTP multipart POST.

This chapter discusses the following topics:

An Overview of MIME Messages

A document in MIME format is referred to as a MIME part. Each MIME part has headers and either contains a message body (either text or binary) or contains additional MIME parts. A MIME part that has a MIME-Version header can be used as a top-level document and is called a MIME message. The following figure shows an example:

images/gnet_mime_parts.png

In this example, E and F have additional subparts that are not shown.

To represent a MIME part, you use the %Net.MIMEPart class, which provides properties that you use to set the headers and contents of the part.

Creating MIME Parts

To create a MIME part, do the following:

  1. Create an instance of %Net.MIMEPart.

  2. Do one of the following:

    • Add a text or binary body. To do so, create an instance of a stream (either text or binary) and set the Body property of your MIME part equal to this stream. Use the standard stream interface to write data into this stream. Do not specify a value for the Parts property.

    • Add a list of MIME parts. To do so, create the MIME parts as described here and set the Parts property equal to a list of these parts. Do not specify a value for the Body property.

  3. Optionally set headers as described in “Setting and Getting MIME Part Headers.”

Setting and Getting MIME Part Headers

You can set values for and get values of the HTTP headers. The following properties of %Net.MIMEPart affect the MIME headers:

  • ContentType — The Internet media type (MIME type) of the Content-Type header. This specifies the Internet media type of the Body data. For example: "text/plain", "text/html", "image/jpeg", "multipart/mixed" and so on.

  • ContentCharset — The charset part of the Content-Type header. If you set this, you must first set the ContentType property. For each MIME part that contains a text body, be sure to set the ContentCharset property appropriately to indicate the character set used in the body. This property should declare the character set that is already used, since %Net.MIMEPart does not perform any conversion.

  • ContentId — The normalized Content-ID header, without the angle brackets (<>) and any leading and trailing spaces.

  • ContentLocation — The normalized Content-Location header, without any leading and trailing spaces.

  • ContentTransferEncoding — The Content-Transfer-Encoding header. This property can be one of the following: "base64" "quoted-printable" "7bit" "8bit"

    There is no default value.

    Important:

    Note that if the content is "base64" encoded, it cannot contain any Unicode characters. If the content you wish to send includes Unicode characters, then make sure to use $ZCONVERT to convert the content to UTF-8, and then base-64 encode it. For example:

    set BinaryText=$ZCONVERT(UnicodeText,"O","UTF8")
    set Base64Encoded=$system.Encryption.Base64Encode(BinaryText)
    Copy code to clipboard

    The recipient must use the reverse process to decode the text:

    set BinaryText=$system.Encryption.Base64Decode(Base64Encoded)
    set UnicodeText=$ZCONVERT(BinaryText,"I","UTF8")
    Copy code to clipboard

The %Net.MIMEPart class provides general methods that you can use to manage the MIME headers:

  • GetHeader() returns the value of a header.

  • NextHeader() gets the next header.

  • SetHeader() sets the value of a header. Typically you use this to set nonstandard headers.

  • RemoveHeader() removes a header.

For complete method signatures and other details, see the class documentation for %Net.MIMEPart.

Specifying an Optional Message Boundary Value

By default, message boundaries are generated automatically. You can specify the message boundary, if needed. To do so, specify a value for the Boundary property. Be sure to use a string that is extremely unlikely to be used in any of the message parts.

Writing MIME Messages

To write MIME messages, use %Net.MIMEWriter as follows:

  1. Create an instance of the %Net.MIMEWriter class.

  2. Optionally specify an output destination. To do so, use one of the following methods of your writer instance: OutputToDevice() (the default), OutputToFile(), or OutputToStream().

  3. Call methods of your writer to write output as needed:

    • Given a header name and value, WriteHeader() writes that header.

    • Given an instance of %Net.MIMEPart, WriteMIMEBody() writes the message body, which can have multiple parts.

      If the message is multipart, this method does not write any headers; it is your responsibility to write them. If the message is not multipart, however, the method does write the headers.

    • Given an instance of %Net.MIMEPart, WriteMIMEMessage() writes the MIME message, including all headers.

    For single-part messages, WriteMIMEBody() and WriteMIMEMessage() produce the same output.

For complete method signatures and other details, see the class documentation for %Net.MIMEPart.

Example: WriteMIMEMessage()

The following example demonstrates the use of WriteMIMEMessage():

ClassMethod WriteMIMEMessage(text As %String,header as %String) as %Status
{
 Set msg=##class(%Net.MIMEPart).%New()
 Set msg.Body=##class(%GlobalCharacterStream).%New()
 Do msg.Body.Write(text)
 
 //specify some headers
 Set msg.ContentType="text/html"
 Set msg.ContentCharset="us-ascii"
 Do msg.SetHeader("Custom-header",header)
 
 //create MIME writer; write MIME message
 Set writer=##class(%Net.MIMEWriter).%New()
 Set status=writer.WriteMIMEMessage(msg)
 
 If $$$ISERR(status) do $system.Status.DisplayError(status)
 Quit $$$OK
}
Copy code to clipboard

The following Terminal session shows this method in use:

GNET> Set text = "message text"
 
GNET> Set header="my header value"
 
GNET> Do ##class(GNET.MIME).WriteMIMEMessage(text,header)
CONTENT-TYPE: text/html
Custom-header: my header value
 
message text
 
GNET>
Copy code to clipboard

Reading MIME Messages

To read MIME messages, use %Net.MIMEReader, as follows:

  1. Create an instance of the %Net.MIMEReader class.

  2. Specify the source of input. To do so, use one of the following methods of your reader instance: OpenFile() or OpenStream().

  3. Call the ReadMIMEMessage() method of your reader instance. This method returns an instance of %Net.MIMEPart by reference as the first argument. It returns a status, which you should check.

For complete method signatures and other details, see the class documentation for %Net.MIMEPart.