PDF 文書ファイルをダウンロードする (1309 KB)
Chapter 3 Enqueuing MessagesThe MTA SDK provides routines with which to construct a mail message and then submit the message to the MTA. The MTA then effects delivery of the message to its recipients. The act of submitting a message to the MTA for delivery is referred to as “enqueuing a message.” This choice of terminology reflects the fact that each message submitted to the MTA for delivery is placed into one or more message queues. Using its configuration, the MTA determines how to route each message to its destination and which message queues to place each the message into. However, programs enqueuing messages do not need to concern themselves with these details; they merely supply the message’s list of recipients and the message itself. The recipients are specified one-by-one as RFC 2822 conformant Internet email addresses. The message header and content is supplied in the form of an RFC 2822 and MIME conformant email message. When starting a coding project to enqueue messages to the MTA, always stop to consider whether simply using SMTP will be acceptable. The advantage of using SMTP is that it will work with any MTA SMTP server, making it portable. The disadvantages are poorer performance and lack of flexibility and control. This chapter covers the following enqueuing topics: Basic Steps to Enqueue MessagesThe basic steps necessary to enqueue one or more messages to the MTA are:
In Step 2e, mtaEnqueueFinish() commits the message to disk. As part of the enqueue process, the MTA performs any access checks, size checks, format conversions, address rewritings, and other tasks called for by the site’s MTA configuration. After these steps are completed and the message has been successfully written to disk, mtaEnqueueFinish() returns. Other MTA processes controlled by the MTA Job Controller then begin processing the new message so as to effect its delivery. In fact, these processes may begin handling the new message before mtaEnqueueFinish() even returns. As such, mtaEnqeueueFinish() doesn’t block waiting on these processes; it returns as soon as all requisite copies of the enqueued message have been safely written to disk. The subsequent handling of the newly enqueued message is performed by other MTA processes, and the program which enqueued the message isn’t left waiting for them. A message submission can be aborted at any point in Step 2 by calling either mtaEnqueueFinish() with the MTA_ABORT option specified or mtaDone(). Using the first method, mtaEnqueueFinish() aborts only the specified message enqueue context while allowing additional messages to be enqueued. Whereas, mtaDone() aborts all active message enqueue contexts in all threads, and deallocates SDK resources disallowing any further submission attempts until the SDK is again initialized. Originating MessagesMessages enqueued to the MTA fall into one of two broad classes: new messages being originated and messages which were originated elsewhere and which are being transferred into the MTA. The former are typically the product of a local user agent or utility which uses the MTA SDK. The latter are generated by remote user agents, and received by local programs such as SMTP or HTTP servers which then enqueue them to the MTA for routing or delivery or both. In either case, it is the job of the MTA to route the message to its destination, be it a local message store or a remote MTA. The only distinction the MTA SDK makes between these two cases occurs when the message’s recipient addresses are specified. For new messages being originated, the recipient addresses should be added to both the message’s header and its envelope. For messages originated elsewhere, the recipient addresses should only be added to the message’s envelope. For a discussion of messages originated elsewhere, see Transferring Messages into the MTA, and Intermediate Processing Channels. When originating a new message, it is easiest to use the MTA_TO, MTA_CC, and MTA_BCC item codes with mtaEnqueueTo(). That tells the SDK to use the specified addresses as both the envelope recipient list and to put them into the message’s header. When using this approach, do not specify any From:, To:, Cc:, or Bcc: header lines in the supplied message’s header; the SDK will add them automatically. An example of using this approach is found in the section that follows. A Simple Example of Enqueuing a MessageThe program shown in Example 3–1 demonstrates how to enqueue a simple “Hello World” message. The originator address associated with the message is that of the MTA postmaster. The recipient address can be specified on the invocation command line. After the Messaging Server product is installed, this program can be found in the following location: msg_server_base/examples/mtasdk/ Note that certain lines of code have numbered comments immediately preceding them of the format: /* This generates output line N */ where N corresponds to the numbers found next to certain output lines in the sample output in Enqueuing a Message Example Output. Refer to Running Your Test Programs for information on how to run the sample program. Example 3–1 Enqueuing a Message
Enqueuing a Message Example OutputThe example that follows shows the output generated by the enqueuing example. Comment numbers correspond to the numbered comments in Example 3–1.
Transferring Messages into the MTAWhen transferring a message originated elsewhere into the MTA, programs should use the MTA_ENV_TO item code with mtaEnqueueTo(). This way, each of the recipient addresses will only be added to the message’s envelope, and not to its already constructed header. Additionally, supply the message’s header as-is. Do not remove or add any origination or destination header lines unless necessary. Failure to use the MTA_ENV_TO item code will typically cause the SDK to add Resent- header lines to the message’s header. A Complex Dequeuing Example, and A Simple Virus Scanner Example both illustrate the use of the MTA_ENV_TO item code. Intermediate Processing ChannelsLike programs which transfer messages into the MTA, intermediate processing channels should also use the MTA_ENV_TO item code with mtaEnqueueTo(). When re-enqueuing a message, intermediate processing channels should also preserve any MTA envelope fields present in the message being re-enqueued. This is done using the MTA_DQ_CONTEXT item code in conjunction with mtaEnqueueStart() and mtaEnqueueTo(). Failure to preserve these envelope fields can result in loss of delivery receipt requests, special delivery flags, and other flags which influence handling and delivery of the message. A Complex Dequeuing Example and A Simple Virus Scanner Example both illustrate the use of the MTA_ENV_TO and MTA_DQ_CONTEXT item codes. item codes. Both of those examples represent intermediate processing channels that handle previously constructed messages. As such, they do not need to alter the existing message header, and they preserve any MTA envelope fields. Delivery Processing Options (Envelope Fields)A variety of delivery processing options may be set through the MTA SDK. These options are then stored in the message’s envelope and are generically referred to as “envelope fields.” Options which pertain to the message as a whole are set with mtaEnqueueStart(). Options which pertain to a specific recipient of the message are set with mtaEnqueueTo(). These options, per message and per recipient, include the following:
For additional information, see the descriptions of mtaEnqueueStart(), and mtaEnqueueTo(). Order DependenciesWhen you are constructing programs, there is a calling order for the MTA SDK routines that must be observed; for a given enqueue context, some routines must be called before others. Figure 3–1 visually depicts the calling order dependency of the message enqueue routines. To the right of each routine name appears a horizontal line segment, possibly broken across a column, for example, mtaEnqueueWrite(). Routines for which two horizontal line segments, one atop the other, appear are required routines; that is, routines that must be called in order to successfully enqueue a message. These routines are mtaEnqueueStart(), mtaEnqueueTo(), and mtaEnqueueFinish(). To determine at which point a routine may be called, start in the leftmost column and work towards the rightmost column. Any routine whose line segment lies in the first (leftmost) column may be called first. Any routine whose line segment falls in the second column may next be called, after which any routine whose line segment falls in the third column may be called, and so forth. When more than one routine appears in the same column, any or all of those routines may be called in any order. Progression from left to right across the columns is mandated by the need to call the required routines. Of the required routines, only mtaEnqueueTo() may be called multiple times for a given message. Figure 3–1 Calling order Dependency for Message Enqueue Routines
|
||||||||||||||||||||||||||||||