RFC 3391
The MIME Application/Vnd.pwg-multiplexed Content-Type
RFC 3391 π The MIME Application/Vnd.pwg-multiplexed Content-Type
Okay bestie, let's get into it π This is RFC 3391, written by R. Herriot and published in December 2002. It's an Informational doc, so it's info for the Internet community, not a standard π The title block doesn't list any RFCs it obsoletes or updates β¨
Status of This Memo πΈ
This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.
Copyright Notice π«Ά
Copyright (C) The Internet Society (2002). All Rights Reserved.
IESG Note π
Okay so the IESG is being very clear here π They think this media type is only a good idea when the producer totally knows what the consumer can and can't handle. The big deal is that this mechanism depends heavily on the producer knowing when the consumer will need a particular component of a multipart object. But consumers are all different, and different consumers might need different things at different times π This mechanism gives a producer no way to figure out what a particular consumer needs or how to accommodate it.
If the producer doesn't know the consumer's capabilities, the IESG says you should look at other options first, like a protocol based on BEEP π¦ BEEP can do two-way communication between the producer and consumer, so it's worth considering.
Abstract π
The Application/Vnd.pwg-multiplexed content-type is kind of like Multipart/Related: it's a way to represent objects made of multiple components β¨ An Application/Vnd.pwg-multiplexed entity is a sequence of chunks, and each chunk holds a MIME message or part of one. Each MIME message is a component of the compound object, the same way a body part of a Multipart/Related entity is a component.
Here's the lowkey big difference π With a Multipart/Related entity, a body part and whatever references it in some other body part can be separated by lots of octets. With Application/Vnd.pwg-multiplexed, a message and its reference in another message can be made really close together by chunking the message that contains the reference. For example, say a long message references images, and the producer doesn't know it needs each image until it generates the reference. Then Application/Vnd.pwg-multiplexed lets the consumer handle the reference and the image before it has to consume the whole long message. That's super important for printing and scanning apps π¨οΈ
This document defines the Application/Vnd.pwg-multiplexed content-type and also gives examples of how to use it π
Table of Contents π
1. Introduction....................................................2
2. Terminology.....................................................7
3. Details.........................................................9
3.1 Syntax of Application/Vnd.pwg-multiplexed Contents...........10
3.2 Parameters for Application/Vnd.pwg-multiplexed...............12
3.2.1 The "type" Parameter.......................................12
3.2.2 Syntax.....................................................12
4. Handling Application/Vnd.pwg-multiplexed Entities..............12
5. Examples.......................................................13
5.1 Example With Multipart/Related...............................14
5.2 Examples with Application/Vnd.pwg-multiplexed................15
5.2.1 Example Where Each Chunk Has a Complete Message............15
5.2.2 Example of Chunking the Root Message.......................17
5.2.3 Example of Chunking the Several Messages...................18
5.2.4 Example of Chunks with Empty Payloads......................20
6. Security Considerations........................................22
7. Registration Information for Application/Vnd.pwg-multiplexed...22
8. Acknowledgments................................................23
9. References.....................................................23
10. Author's Address..............................................24
11. Full Copyright Statement......................................25
1. Introduction π§
Simple MIME content-types, like text/plain, are a way to represent a simple object, like a text document π The Multipart/Related [RFC2387] content-type is for representing a compound object, like a text document with two gif images πΌοΈ
A compound object is made of multiple components π One of them is the root component, which contains references to the other components of the compound object. Those components can also contain references to other components, so it's a whole web πΈοΈ For example, a compound object could be a root html text component plus two gif image components, and both images are referenced by the root component.
A compound object and a component are both abstractions β¨ To send them over the wire or write them to storage, each one needs a representation. A "Multipart/Related entity" is one possible representation of a compound object, and a "body part" is one possible representation of a component.
Here's the tea β Multipart/Related is not a great solution for apps that need each component to sit close to its reference in the root component. So this document defines a new MIME content-type, Application/Vnd.pwg-multiplexed, which is a better fit for some apps π¦ Like Multipart/Related, it gives a common way to represent a compound object. A Multipart/Related entity is a sequence of body parts separated by boundary strings, and each body part represents a component. An Application/Vnd.pwg-multiplexed entity is a sequence of chunks, and each chunk's length is specified in its chunk header. Each chunk contains a message or part of a message, and each message represents a component of the compound object. Chunks from different messages can be interleaved π HTTP is the typical transport for an Application/Vnd.pwg-multiplexed entity over the wire. An Application/Vnd.pwg-multiplexed entity could also be stored in a Microsoft HTML (message/rfc822) file whose suffix is .mht ποΈ
The next bit gives three example apps π§ββοΈ For each one, the doc talks about the solution using Application/Vnd.pwg-multiplexed, Multipart/Related, and BEEP [RFC3080].
Example 1: a printing application. π¨οΈ A Producer creates a print stream that's a really long series of page descriptions, and each page description references one or more images. The root component is that long series of page descriptions. An image can be referenced from multiple page descriptions, and there's a mechanism to say when an image has no more references (meaning the image is out of scope) π The Producer doesn't know which images go with a page until it generates that page. The Consumer is assumed to have enough storage to hold all the in-scope images and enough of the root component to process at least one page. The Producer doesn't need to know anything about the Consumer's storage capabilities to create an entity the Consumer can successfully process. Still, the Producer needs to be prudent about how many images are in scope at any given time. And yes, a malicious Producer might try to exceed the Consumer's storage capabilities, so the Consumer must guard against those entities (see section 6) π Here are the ways to represent this compound object:
- With the
Application/Vnd.pwg-multiplexedcontent-type, each image is a message and the root component is a message too. The Producer breaks the root component message into chunks, with each image message showing up shortly before its first reference. When the Consumer hits a reference, it can assume it already received the referenced image in an earlier chunk π₯Ή - With the
Multipart/Relatedcontent-type, each image must either come before or after the root component.- If the images come after the root component, the Consumer has to read all the remaining pages of the root component before it can print the first page that references those images. The Consumer must wait to print such a page until it has the entire root component, and it may not have the space to hold the remaining pages π΅
- If the images come before the root component, the Producer must figure out and send all of those images before it sends the root component. The Consumer must, in the best case, wait some extra time before it gets the first page of the root component. In the worst case, the Consumer may not have enough storage for all the images π¬
- The
Multipart/Relatedsolution isn't a good one because of the wait time and because, in some cases, the Consumer may not have enough storage for all of the images.
- With BEEP, the images and root component can be sent over separate channels. The Producer can push each image when it hits the first reference, or the Consumer can request it when it hits the first reference. The over-the-wire stream of octets looks similar to an
Application/Vnd.pwg-multiplexedentity. But there's a big difference in behavior for a printing app π WithApplication/Vnd.pwg-multiplexed, the Producer puts each image message before its first reference, so when the Consumer hits a reference, the image is guaranteed to be on the printer. With BEEP, if the Consumer pulls the image, it has to wait while the image comes over the network. If the Producer pushes the image, BEEP may put the image message after its first reference, and the Consumer may still have to wait for it. A high-speed printer shouldn't have to risk waiting for images, otherwise it can't run at full speed ποΈπ¨
Example 2: a scanning (fax-like) application. π The Producer is a scanner that scans pages and sends them along with a vnd.pwg-xhtml-print+xml root component that contains references to each page image. Each page is referenced exactly once in the root component. The Consumer is a printer that consumes vnd.pwg-xhtml-print+xml entities and their attachments. In other words, the Consumer isn't limited to print jobs that come from scanners π The Producer and Consumer are each assumed to have enough storage for a few page images and most, if not all, of the root component. The Producer doesn't need any extra knowledge of the Consumer's storage capabilities to create an entity the Consumer can successfully process. Of course, a malicious Producer might try to exceed the Consumer's storage capabilities, and the Consumer must guard against such entities (see section 6) π‘οΈ Here are the ways to represent this compound object:
- With the
Application/Vnd.pwg-multiplexedcontent-type, each page image is a message and the root component is a message. The Producer breaks the root component message into chunks, with each image message just before or just after its reference β¨
Okay so picture this: with Multipart/Related, the images can't come before the root component π. The Consumer might not have room to hold them until the root shows up, the printer could mess up the job, and the Producer wouldn't even know π. So the images must follow the root component, which means the Producer has to scan every page before it can send the first one π. At the very least, printing gets delayed until everything is scanned, and in the worst case the Producer doesn't have enough memory to buffer the images and the whole job fails π.
With BEEP, it's the same problem as the previous example, except speed isn't as big a deal here π¦. So BEEP is a viable option for this one β¨.
Example 3: a printing application. A Producer makes a print stream made of a series of pages, and each page references zero or more images. Each image is referenced exactly once. The Producer doesn't know which images go with a page until it generates that page, and it doesn't know the layout details, because the Consumer handles layout π§. The Producer has enough storage to send the root component and all the images. However, it may not have enough storage to hold the entire root component or all the octets of any single image. The Consumer is presumed to have enough storage to render the root component and to render each image, but it may not have enough storage to hold the entire root component or all the octets of any of the images either π₯Ί. The Producer doesn't determine the Consumer's storage capabilities. Instead, it arranges the components so the Consumer is most likely to succeed πΈ. Of course, a malicious Producer might try to exceed the Consumer's storage capabilities, and the Consumer must guard against that kind of entity (see section 6) π¨. Here are the ways to represent this compound object π.
With the Application/Vnd.pwg-multiplexed content-type, each image is its own message, and the root component is a message too. The Producer breaks the root component message into chunks, with each image message placed right after its reference. The references come first so the Consumer knows where each image goes before it processes that image. This strategy minimizes storage needs for both the Producer and the Consumer, and it's a good strategy if something fails π«Ά. Here are the cases to think about:
- a) When the document is made of vertically aligned blocks, where each block contains either lines of text or a single image, the sequence of chunks is the same as the sequence of printable blocks, which keeps the Consumer's buffering needs low β¨.
- b) When a block can contain N side-by-side images, the Consumer must buffer N-1 images unless the Producer interleaves the images. If the Producer doesn't interleave them and the Consumer runs out of storage before it has received N-1 images, it can print what it has and print the remaining images below. It's not what the Producer intended, but it's better than nothing π. If the Producer does interleave the images and the Consumer runs out of storage before it has received the bands of N images, the Consumer would print portions of images mixed in with portions of other images, which is messy π. So, a Producer should not interleave images π«.
- c) When a block contains text and an image side-by-side (in other words, run-around text), there are extra buffering requirements π. When the Consumer processes the text that follows the reference, it places some of that text next to the image (the run-around text) and puts the rest after the image. The Producer doesn't know where the run-around ends, so it doesn't know where to end the text chunk and start the image chunk. If the Producer ends the text too soon, the Consumer either has to process the entire image (if it has enough storage) to get the remaining run-around text, or it ends the run-around text early. If the Producer ends the text too late, the Consumer may have to store too much text and might place the image later than the Producer asked for. Because text data takes way less storage than image data, a good strategy for the Producer is to err on the side of sending too much text rather than too little before the image data π .
- d) When a block contains text and multiple side-by-side images, the problem becomes a mix of items b) and c) above π.
The Application/Vnd.pwg-multiplexed content-type can be made to work in this example, but a Consumer needs failure strategies, and the result may not be quite what the Producer intended π₯². With Multipart/Related, the images can't come before the root component, because the Consumer might not have space to store them until the root arrived. Also, the images can't come after the root component either, because the Consumer might not have enough storage for the root component before the first image arrives π©. So Multipart/Related is not an acceptable solution for this example π«.
With BEEP, the Producer can send the root component on channel 1, and the Consumer can request images on even-numbered channels when it hits a reference π. This solution is more flexible than Application/Vnd.pwg-multiplexed. If there are side-by-side images and/or run-around text, the Consumer can request bands of each image or run-around text over separate channels π¦.
In all of these examples, Application/Vnd.pwg-multiplexed is a much better solution than Multipart/Related. However, it's evenly matched with BEEP π€Ό. For applications where speed matters and the ordering of chunks matters to avoid printing delays, Application/Vnd.pwg-multiplexed is the best pick ποΈ. For applications where the Consumer needs more control over the ordering of the received octets, BEEP is the best pick π.
2. Terminology β¨
This document uses some of the MIME terms defined in [RFC2045]. Here are the terms used in this document π:
- Entity: the headers and the content. In this document, "entity" describes all the octets that represent a compound object π.
- Message: an entity as in [RFC2045]. In this document, "message" describes all the octets that represent one component of a compound object. That means it has MIME headers and content πΈ.
- Body Part: an entity inside a multipart. A body part is the headers and content (i.e., the octets) between the multipart boundary strings, not including the CRLF at the beginning and end π. This document never uses "entity" to mean "body part" π ββοΈ.
- Headers: the initial lines of an entity, message, or body part. An empty line (i.e., two adjacent CRLFs) ends the headers. Sometimes the term "MIME header" is used instead of just "header" π§.
- Content: the part of an entity, message, or body part that follows the headers (i.e., follows the two adjacent CRLFs). The content of a body part ends at the octet before the CRLF that comes before the multipart boundary string. The content of a message ends at the octets specified by the length field in the Chunk Header π«Ά.
This document uses the following additional terms π.
- Chunk: a chunk of data, made of a chunk header, a chunk payload, and a CRLF π.
- Chunk Header: the first line of a chunk. The line consists of the
CHKkeyword, the message number, the length, and the continuation indicator, each separated by a single space character (ASCII 32). A CRLF ends the line. Each message in anApplication/Vnd.pwg-multiplexedentity has a message number that normally differs from the message numbers of all other messages in that entity. The message number 0 is reserved for the final Chunk Header in theApplication/Vnd.pwg-multiplexedentity π’. - Chunk Payload: the octets between the Chunk Header and the Chunk Header of the next chunk. The length field in the header specifies the number of octets in the Chunk Payload. The Chunk Payload is either a complete message or a part of a message. The continuation field in the header specifies whether the chunk is the last chunk of the message π¦.
- CRLF: the sequence of octets for the two US-ASCII characters CR (decimal value 13) and LF (decimal value 10), which together, in this order, denote a line break. A CRLF ends each chunk to visually separate it from the next chunk header π.
- Consumer: the software that receives and processes a MIME entity, e.g., software in a printer or software that reads a file π¨οΈ.
- Producer: the software that creates and sends a MIME entity, e.g., software in a scanner or software that writes a file πΈ.
3. Details β¨
okay so Application/Vnd.pwg-multiplexed is giving Multipart/Related energy π. It's meant to hold a compound object made of several inter-related components. This doc doesn't spell out how those relationships are represented, BUT [RFC2557] has examples of Multipart/Related entities that use the Content-ID and Content-Location headers to identify body parts, and URLs (including the "cid" URL) to reference them. It is expected that Application/Vnd.pwg-multiplexed entities would use the patterns described in [RFC2557]. π
For an Application/Vnd.pwg-multiplexed entity there is exactly one parameter on the Content-Type header. It's a "type" parameter, lowkey just like the "type" parameter on Multipart/Related. The value of the "type" parameter MUST be the content-type of the root message, and it effectively tells you the type of the whole compound object π.
An Application/Vnd.pwg-multiplexed entity is a sequence of chunks. Each chunk is made of a chunk header, a chunk payload and a CRLF π¦.
- The chunk header is a
CHKkeyword, then the message number, the chunk payload length, whether this is the last chunk of a message and, finally, aCRLF. The length field means you don't need the boundary strings that Multipart uses, which is so iconic π. (See section 3.1 for the syntax of a chunk header). - The chunk payload is a sequence of octets that is either a complete message or a part of a message.
- The
CRLFgives visual separation from the next chunk.
Each message is a component of the compound object, and it's intended to have exactly the same representation, octet for octet, as a body part of a Multipart/Related entity that represents the same component π§. When a message gets split across several chunks, those chunks don't have to be contiguous.
Okay, now the contents of an Application/Vnd.pwg-multiplexed entity have these properties, and they're the main character rules π
:
- The first chunk contains a complete or partial message that (in either case) represents the root component of the compound object.
- Additional chunks contain messages or partial messages that represent some component of the compound object.
- The final chunk's header contains a message number of 0, a length of 0 and a last-chunk-of-message mark (i.e., the chunk header line is
CHK 0 0 LAST). The final chunk contains no chunk payload π. - A message can be broken into multiple parts, and each break can occur anywhere within the message. Each part of the message is zero or more bytes in length, and each part is the contents of its own chunk. The order of the chunks within the
Application/Vnd.pwg-multiplexedentity MUST be the same as the order of the parts within the message πΈ. - A message represents a component of a compound object, and it's intended to have exactly the same representation, octet for octet, as a body part of a Multipart/Related entity that represents the same component. In particular, the message MAY contain a
Content-Typeheader to specify the content-type of the message content. Also, the message MAY contain aContent-IDheader and/orContent-Locationheader to identify a message that is referenced from within another message. If a message contains noContent-Typeheader, then the message has an implicit content-type oftext/plain; charset=us-ascii, cf. [RFC2045] π₯.
See section 4 for a discussion displaying an Application/Vnd.pwg-multiplexed entity π.
3.1 Syntax of Application/Vnd.pwg-multiplexed Contents
The ABNF [RFC2234] for the contents of an Application/Vnd.pwg-multiplexed entity is:
contents = *chunk finalChunk
chunk = header payload CRLF
header = "CHK" SP messageNumber SP length SP isMore CRLF
messageNumber = 1..2147483647
length = 0..2147483647
isMore = "MORE" / "LAST"
payload = *OCTET
finalChunk = finalHeader CRLF
finalHeader = "CHK" SP "0" SP "0" SP "LAST" CRLF
The messageNumber field tells you which message the chunk belongs to. See the end of this section for more details π§.
The length field is the number of octets in the chunk payload (written as "payload" in the ABNF). The first octet of the chunk payload is the one right after the LF (i.e., final octet) of the chunk header. The last octet of the chunk payload is the one right before the two octets CRLF that end the chunk.
The isMore field is "LAST" for the last chunk of a message and "MORE" for all the other chunks of a message π.
Normally, each message in an Application/Vnd.pwg-multiplexed entity has a unique message number, and a message is the concatenation of all the octets from the one or more chunks with the same message number. The isMore field of the chunk header of the last chunk of each message MUST have a value of "LAST", and the isMore field of the chunk header of all other chunks MUST have a value of "MORE" π.
Two or more messages MAY have the same message number, though such reuse of message numbers is NOT RECOMMENDED. The chunks with the same message number represent a sequence of one or more messages, where the isMore field of the chunk header of the last chunk of each message has a value of "LAST". All chunks whose isMore field has the value "MORE" belong to the same message as the next chunk (in sequence) whose isMore field has the value "LAST". In other words, if two messages have the same message number, the last chunk of the first message must occur before the first chunk of the second message π.
The behavior of the Consumer is undefined if the final Chunk (i.e., the Chunk whose chunk header is CHK 0 0 LAST) occurs before the last chunk of every message occurs π.
Two adjacent chunks usually have different message numbers. However, they MAY have the same message number. If two adjacent chunks have the same message number, the two chunks could be combined into a single chunk, but they need not be combined π.
The number of octets in a chunk payload MAY be zero, and an Application/Vnd.pwg-multiplexed entity MAY contain any number of chunks with zero octets of chunk payload. For example, the last chunk of each message MAY contain zero octets for programming convenience. As another example, suppose that a particular compound object format requires that referenced messages occur before the root message. This document requires that the first chunk of an Application/Vnd.pwg-multiplexed entity contain the root message or a part of it. So, the first chunk contains a chunk payload of zero octets, with the first octet of the root message in the second chunk. That is, all of the message headers of the root message are in the second chunk. As an extreme but unlikely example, it would be possible to have a message broken into ten chunks with zero octet chunk payloads in all chunks except for chunks 4 and 7 π.
3.2 Parameters for Application/Vnd.pwg-multiplexed
This section defines additional parameters for Application/Vnd.pwg-multiplexed π§.
3.2.1 The "type" Parameter
The type parameter MUST be specified. Its value is the content-type of the "root" message. It lets a Consumer work out the content-type without looking at the enclosed message. If the value of the type parameter differs from the content-type of the root message, the Consumer's behavior is undefined π.
3.2.2 Syntax
The syntax for "parameter" is:
parameter := "type" "=" type "/" subtype ; cf. [RFC2045]
4. Handling Application/Vnd.pwg-multiplexed Entities π
The application that handles the Application/Vnd.pwg-multiplexed entity is responsible for displaying it. However, Application/Vnd.pwg-multiplexed messages MAY contain Content-Disposition headers that suggest how a message should be displayed and stored, and in some cases the application MAY pay attention to those headers π.
As a reminder, Content-Disposition headers [RFC1806] let the sender suggest presentation styles for MIME messages. There are two presentation styles, 'inline' and 'attachment'. Content-Disposition headers can have a parameter that specifies a suggested file name for storage β¨.
There are three cases to consider for handling Application/Vnd.pwg-multiplexed entities π¦:
- a) The Consumer recognizes
Application/Vnd.pwg-multiplexedand the content-type of the root. The Consumer determines the presentation style for the compound object, and it handles the display of the components of the compound object in the context of the compound object. In this case, theContent-Dispositionheader information is redundant or even misleading, and the Consumer SHALL ignore it for purposes of display. The Consumer MAY use the suggested file name if the entity is stored π. - b) The Consumer recognizes
Application/Vnd.pwg-multiplexed, but not the content-type of the root. The Consumer will give the user the choice of suppressing the entireApplication/Vnd.pwg-multiplexedentity or treating it as a Multipart/Mixed entity where each message is a body part of the Multipart/Mixed entity. In this case (where the entity is not suppressed), the Consumer MAY find theContent-Dispositioninformation useful for displaying each body part of the resulting Multipart/Mixed entity. If a body part has noContent-Dispositionheader, the Consumer SHOULD display the body part as an attachment πΈ. - c) The Consumer does not recognize
Application/Vnd.pwg-multiplexed. The Consumer treats the entity as opaque and can do nothing with it π.
5. Examples β¨
Okay bestie, this section is the fun part π There are five examples, and each one is a different way of writing down the same compound object π
The object has four components: one XHTML text component and three image components. The images are binary, so <<binary data>> and <<part of binary data>> just stand in for all or part of each image's bytes π¦ Two images could sit side by side, and the third shows up later in the document. All the images have a Content-Id, two of them also have a Content-Location, and one image points at that Content-Location πΈ
The first example is a Multipart/Related version of the object, so you can compare it with what you already know π§ The other four are Application/Vnd.pwg-multiplexed versions of the same object. In example two, every chunk holds a whole message. In example three, the XHTML message is chopped into 3 chunks, and those chunks are interleaved with the three image messages π In example four, the XHTML message gets split into 4 chunks, the two side-by-side images are each split across two chunks, and the XHTML chunks are interleaved among the image chunks β¨ In example five, you get chunks with empty payloads and adjacent chunks that share the same message number π
Example five might look pointless, but it's actually kinda practical π When a buffer fills up, it can be easiest to just write a chunk and not care whether the previous one had the same message number. It can also be easiest to end a message with an empty chunk. And here's the big one: the Application/Vnd.pwg-multiplexed content-type says the first chunk has to be part of the root message. Sometimes the Producer would rather start the root message after some attachments, so a chunk is allowed to be empty. That means the first chunk of the root message can be empty, with no headers at all, and the Producer just doesn't generate any octets for that chunk π«Ά
Every body part of the Multipart/Related entity, and every message in the Application/Vnd.pwg-multiplexed entity, has a content-disposition header. The Consumer uses that header following the rules in section 4 π¦ Make sure you notice where the content-disposition headers sit in the examples π
5.1 Example With Multipart/Related
Here the compound object is written as a Multipart/Related entity, so you can compare it with the Application/Vnd.pwg-multiplexed versions later π
Content-Type: multipart/related; boundary="boundary-example";
type="text/xhtml+xml"
--boundary-example
Content-ID: <49568.44343xxx@foo.com>
Content-Type: application/vnd.pwg-xhtml-print+xml
Content-Disposition: inline
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1">
<body>
<p>some text
<img src="cid:49568.45876xxx@foo.com"/>
<img src="http://foo.com/images/image2.gif"/>
some more text after the images
</p>
<p>some more text without images
</p>
<p>some more text
<img src="cid:49568.47333xxx@foo.com"/>
</p>
<p>some final text
</p>
</body>
</html>
--boundary-example
Content-ID: <49568.45876xxx@foo.com>
Content-Location: http://foo.com/images/image1.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
--boundary-example
Content-ID: <49568.46000xxx@foo.com>
Content-Location: http://foo.com/images/image2.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
--boundary-example
Content-ID: <49568.47333xxx@foo.com>
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
--boundary-example--
5.2 Examples with Application/Vnd.pwg-multiplexed
The next four examples show the same compound object written as Application/Vnd.pwg-multiplexed entities π Heads up: each CRLF is drawn as a visual line break here, so don't panic when the lines look a little different π
5.2.1 Example Where Each Chunk Has a Complete Message
In this one, the compound object is an Application/Vnd.pwg-multiplexed entity, and every chunk carries an entire message. None of the messages get split across chunks π Each message is identical to the matching body part from the Multipart/Related example back in 5.1 π¦
Content-Type: application/vnd.pwg-multiplexed;
type="application/vnd.pwg-xhtml-print+xml"
CHK 1 550 LAST
Content-ID: <49568.44343xxx@foo.com>
Content-Type: application/vnd.pwg-xhtml-print+xml
Content-Disposition: inline
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1">
<body>
<p>some text
<img src="cid:49568.45876xxx@foo.com"/>
<img src="http://foo.com/images/image2.gif"/>
some more text after the images
</p>
<p>some more text without images
</p>
<p>some more text
<img src="cid:49568.47333xxx@foo.com"/>
</p>
<p>some final text
</p>
</body>
</html>
CHK 2 6346 LAST
Content-ID: <49568.45876xxx@foo.com>
Content-Location: http://foo.com/images/image1.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 3 6401 LAST
Content-ID: <49568.46000xxx@foo.com>
Content-Location: http://foo.com/images/image2.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 4 7603 LAST
Content-ID: <49568.47333xxx@foo.com>
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 0 0 LAST
5.2.2 Example of Chunking the Root Message
This time the XHTML message is split into 3 pieces, so the reference to an image is as close as possible to the start of its chunk π§ The chunk holding the referenced image message comes just before the chunk with the reference, which keeps the distance between reference and referenced message as small as it can be β¨
Quick aside: there are other valid arrangements too (check out the third example in section 5.2.3). A sender could split the XHTML message so the reference sits as close as possible to the end of its chunk. In that case, the chunk with the referenced image message should come just after the chunk with the reference. A sender can also mix the two strategies π
Content-Type: application/vnd.pwg-multiplexed;
type=" application/vnd.pwg-xhtml-print+xml"
CHK 1 267 MORE
Content-ID: <49568.44343xxx@foo.com>
Content-Type: application/vnd.pwg-xhtml-print+xml
Content-Disposition: inline
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1">
<body>
<p>some text
CHK 2 6346 LAST
Content-ID: <49568.45876xxx@foo.com>
Content-Location: http://foo.com/images/image1.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 3 6401 LAST
Content-ID: <49568.46000xxx@foo.com>
Content-Location: http://foo.com/images/image2.gif
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 1 166 MORE
<img src="cid:49568.45876xxx@foo.com"/>
<img src="http://foo.com/images/image2.gif"/>
some more text after the images
</p>
<p>some more text without images
</p>
<p>some more text
CHK 4 7603 LAST
Content-ID: <49568.47333xxx@foo.com>
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 1 80 LAST
<img src="cid:49568.47333xxx@foo.com"/>
</p>
<p>some final text
</p>
</body>
</html>
CHK 0 0 LAST
5.2.3 Example of Chunking the Several Messages
Now the XHTML message is split into 4 pieces, so each image reference sits as close as possible to either the start or the end of its chunk π₯ The references to the first and second images come right after the images they point to, while the reference to the third image comes right before it. The distance between reference and referenced message stays small this way πΈ On top of that, the first two image messages are each split into two chunks π
Content-Type: application/vnd.pwg-multiplexed;
type=" application/vnd.pwg-xhtml-print+xml"
CHK 1 303 MORE
Content-ID: <49568.44343xxx@foo.com>
Content-Type: application/vnd.pwg-xhtml-print+xml
Content-Disposition: inline
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1">
<body>
<p>some text
CHK 2 184 MORE
Content-ID: <49568.45876xxx@foo.com>
Content-Location: http://foo.com/images/image1.gif
Content-Type: image/gif
Content-Disposition: attachment
<<part of binary data>>
CHK 3 200 MORE
Content-ID: <49568.46000xxx@foo.com>
Content-Location: http://foo.com/images/image2.gif
Content-Type: image/gif
Content-Disposition: attachment
<<part of binary data>>
CHK 1 78 MORE
<img src="cid:49568.45876xxx@foo.com"/>
<img src="http://foo.com/images/image2.gif"/>
CHK 2 6162 LAST
<<part of binary data>>
CHK 3 6201 LAST
<<part of binary data>>
CHK 1 127 MORE
some more text after the images
</p>
<p>some more text without images
</p>
<p>some more text
<img src="cid:49568.47333xxx@foo.com"/>
CHK 4 7603 LAST
Content-ID: <49568.47333xxx@foo.com>
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 1 41 LAST
</p>
<p>some final text
</p>
</body>
</html>
CHK 0 0 LAST
5.2.4. Example of Chunks with Empty Payloads β¨
okay bestie, this one is basically the last example with a twist π Some chunks have a payload of zero octets. The root message starts with an empty chunk, and every message ends with an empty chunk too π It also has two chunks from the same message sitting next to each other. Those could be squished into one chunk, but they might stay separate just for programming convenience π¦
Content-Type: application/vnd.pwg-multiplexed;
type=" application/vnd.pwg-xhtml-print+xml"
CHK 1 0 MORE
CHK 2 184 MORE
Content-ID: <49568.45876xxx@foo.com>
Content-Location: http://foo.com/images/image1.gif
Content-Type: image/gif
Content-Disposition: attachment
<<part of binary data>>
CHK 3 200 MORE
Content-ID: <49568.46000xxx@foo.com>
Content-Location: http://foo.com/images/image2.gif
Content-Type: image/gif
Content-Disposition: attachment
<<part of binary data>>
CHK 1 303 MORE
Content-ID: <49568.44343xxx@foo.com>
Content-Type: application/vnd.pwg-xhtml-print+xml
Content-Disposition: inline
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/TR/xhtml1">
<body>
<p>some text
CHK 2 6162 MORE
<<part of binary data>>
CHK 3 6201 MORE
<<part of binary data>>
CHK 2 0 LAST
CHK 3 0 LAST
CHK 1 78 MORE
<img src="cid:49568.45876xxx@foo.com"/>
<img src="http://foo.com/images/image2.gif"/>
CHK 4 7603 MORE
Content-ID: <49568.47333xxx@foo.com>
Content-Type: image/gif
Content-Disposition: attachment
<<binary data>>
CHK 4 0 LAST
CHK 1 127 MORE
some more text after the images
</p>
<p>some more text without images
</p>
<p>some more text
<img src="cid:49568.47333xxx@foo.com"/>
CHK 1 41 MORE
</p>
<p>some final text
</p>
</body>
</html>
CHK 1 0 LAST
CHK 0 0 LAST
6. Security Considerations π₯
okay this part is seriously important, so no giggling π Every message inside an Application/Vnd.pwg-multiplexed entity has its own security considerations, and those are covered by whatever document defines that message's content-type. This document doesn't cover them π
BUT the whole entity has its own risks too! A buggy or malicious Producer could send an entity that makes a Consumer ask for more storage than it has, even if it has tons of storage. A Consumer must be able to handle all of these scenarios, and any combo of them:
- The chunks of one or more messages are separated by a very large number of octets. In the extreme case some or all of the messages don't terminate, i.e., they don't contain a closing chunk.
- A very large number of messages are started and interleaved before their final chunk occurs.
- A message contains one or more references to other messages that never occur or don't occur for a large number of octets.
- A very large number of referenced messages occur before the Consumer knows that it can discard them.
Main character energy for Consumers: handle the chaos gracefully π
7. Registration Information for Application/Vnd.pwg-multiplexed πΈ
this is the form for registering the media type with IANA, copied from RFC 1590, Appendix A π§ It's giving paperwork, but it's important paperwork β¨
To: iana@iana.org
Subject: Registration of new Media Type
application/Vnd.pwg-multiplexed
Media Type name: Application
Media subtype name: Vendor Tree - vnd.pwg-multiplexed
Required parameters: Type, a media type/subtype.
Optional parameters: No optional parameters
Encoding considerations: Each message of an
Application/Vnd.pwg-multiplexed entity can be
encoded in any manner allowed by the Content-
Type of the message. However, using the
reasoning of Multipart, the
Application/Vnd.pwg-multiplexed entity cannot
be encoded. Otherwise, a message would be
encoded twice, once at the message level and
once at the Application/Vnd.pwg-multiplexed
level.
Security considerations: See section 6 (Security
Considerations) of RFC 3391.
Published specification: RFC 3391.
Person & email address to contact for further information:
Robert Herriot
706 Colorado Ave.
Palo Alto, CA 94303
USA
Phone: 1-650-327-4466
Fax: 1-650-327-4466
EMail: bob@herriot.com
8. Acknowledgments π
big thank-you to everyone who helped out π«Ά Ugo Corda, Dave Crocker, Melinda Sue Grant, Graham Klyne, Carl-Uno Manros, Larry Masinter, Ira McDonald, Chris Newman, Henrik Frystyk Nielsen and Dale R. Worley. Author gives a special shoutout to Chris Newman, who provided invaluable help π
9. References π
these are all the docs cited above, with every detail kept π¦
[RFC1806] Troost, R. and S. Dorner, "Communicating Presentation
Information in Internet Messages: The Content-Disposition
Header", RFC 1806, June 1995.
[RFC1873] Levinson, E. and J. Clark, "Message/External-Body Content-
ID Access Type", RFC 1873, December 1995.
Levinson, E., "Message/External-Body Content-ID Access
Type", Work in Progress.
[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part One: Format of Internet Message
Bodies", RFC 2045, November 1996.
[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part Two: Media Types", RFC 2046,
November 1996.
[RFC2234] Crocker, D. and P. Overell, "Augmented BNF for
SyntaxSpecifications: ABNF", RFC 2234, November 1997.
[RFC2387] Levinson, E., "The MIME Multipart/Related Content-type",
RFC 2387, August 1998.
[RFC2392] Levinson, E., "Content-ID and Message-ID Uniform Resource
Locators", RFC 2392, August 1998.
[RFC2557] Palme, J., "MIME Encapsulation of Aggregate Documents, such
as HTML (MHTML", RFC 2557, March 1999.
[RFC2822] Resnick, P., Editor, "Internet Message Format", RFC 2822,
April 2001.
[RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core",
RFC 3080, March 2001.
10. Author's Address π
reach out to the author here π
Robert Herriot
706 Colorado Ave.
Palo Alto, CA 94303
USA
Phone: 1-650-327-4466
Fax: 1-650-327-4466
EMail: bob@herriot.com
11. Full Copyright Statement β
legal bit, but it's iconic in its own way π
Copyright (C) The Internet Society (2002). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement π
Funding for the RFC Editor function is currently provided by the Internet Society. Thank you, Internet Society π«Άβ¨
π¦ where this page comes from
- ietf: rfc3391 2002-12
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms