| < draft-leiba-imap-implement-guide-00.txt | draft-leiba-imap-implement-guide-01.txt > | |||
|---|---|---|---|---|
| Network Working Group B. Leiba | Network Working Group B. Leiba | |||
| Internet Draft IBM T.J. Watson Research Center | Internet Draft IBM T.J. Watson Research Center | |||
| Document: draft-leiba-imap-implement-guide-00.txt September 1997 | Document: draft-leiba-imap-implement-guide-01.txt September 1997 | |||
| Expires February 1998 | ||||
| IMAP4 Implementation Recommendations | IMAP4 Implementation Recommendations | |||
| Status of this Document | Status of this Document | |||
| This document provides information for the Internet community. This | This document provides information for the Internet community. This | |||
| document does not specify an Internet standard of any kind. | document does not specify an Internet standard of any kind. | |||
| Distribution of this document is unlimited. | Distribution of this document is unlimited. | |||
| This document is an Internet Draft. Internet Drafts are working | This document is an Internet Draft. Internet Drafts are working | |||
| skipping to change at page 2, line 39 ¶ | skipping to change at page 2, line 39 ¶ | |||
| still connected; or the help desk staff can all work out of the same | still connected; or the help desk staff can all work out of the same | |||
| inbox, all seeing the same pool of questions. An important point | inbox, all seeing the same pool of questions. An important point | |||
| about this capability, though is that NO SERVER IS GUARANTEED TO | about this capability, though is that NO SERVER IS GUARANTEED TO | |||
| SUPPORT THIS. If you are selecting an IMAP server and this facility | SUPPORT THIS. If you are selecting an IMAP server and this facility | |||
| is important to you, be sure that the server you choose to install, | is important to you, be sure that the server you choose to install, | |||
| in the configuration you choose to use, supports it. | in the configuration you choose to use, supports it. | |||
| If you are designing a client, you MUST NOT assume that you can | If you are designing a client, you MUST NOT assume that you can | |||
| access the same mailbox more than once at a time. That means | access the same mailbox more than once at a time. That means | |||
| 1. you must handle gracefully the failure of a SELECT command if | 1. you must handle gracefully the failure of a SELECT command if | |||
| the server refuses the second SELECT, | the server refuses the second SELECT, | |||
| 2. you must handle reasonably the severing of your connection (see | 2. you must handle reasonably the severing of your connection (see | |||
| "Severed Connections", below) if the server chooses to allow the | "Severed Connections", below) if the server chooses to allow the | |||
| second SELECT by forcing the first off, | second SELECT by forcing the first off, | |||
| 3. you must avoid making multiple connections to the same mailbox | 3. you must avoid making multiple connections to the same mailbox | |||
| in your own client (for load balancing or other such reasons), and | in your own client (for load balancing or other such reasons), | |||
| and | ||||
| 4. you must avoid using the STATUS command on a mailbox that you | 4. you must avoid using the STATUS command on a mailbox that you | |||
| have selected (with some server implementations the STATUS command | have selected (with some server implementations the STATUS | |||
| has the same problems with multiple access as do the SELECT and | command has the same problems with multiple access as do the | |||
| EXAMINE commands). | SELECT and EXAMINE commands). | |||
| A further note about STATUS: The STATUS command is sometimes used to | A further note about STATUS: The STATUS command is sometimes used to | |||
| check a non-selected mailbox for new mail. This mechanism MUST NOT | check a non-selected mailbox for new mail. This mechanism MUST NOT | |||
| be used to check for new mail in the selected mailbox; section 5.2 of | be used to check for new mail in the selected mailbox; section 5.2 of | |||
| [RFC-2060] specifically forbids this in its last paragraph. | ||||
| Internet DRAFT Implementation Recommendations September 1997 | Internet DRAFT Implementation Recommendations September 1997 | |||
| [RFC-2060] specifically forbids this in its last paragraph. | ||||
| 3.1.2. Severed Connections | 3.1.2. Severed Connections | |||
| The client/server connection may be severed for one of three reasons: | The client/server connection may be severed for one of three reasons: | |||
| the client severs the connection, the server severs the connection, | the client severs the connection, the server severs the connection, | |||
| or the connection is severed by outside forces beyond the control of | or the connection is severed by outside forces beyond the control of | |||
| the client and the server (a telephone line drops, for example). | the client and the server (a telephone line drops, for example). | |||
| Clients and servers must both deal with these situations. | Clients and servers must both deal with these situations. | |||
| When the client wants to sever a connection, it's usually because it | When the client wants to sever a connection, it's usually because it | |||
| has finished the work it needed to do on that connection. The client | has finished the work it needed to do on that connection. The client | |||
| SHOULD send a LOGOUT command, wait for the tagged response, and then | SHOULD send a LOGOUT command, wait for the tagged response, and then | |||
| close the socket. But note that, while this is what's intended in | close the socket. But note that, while this is what's intended in | |||
| the protocol design, there isn't universal agreement here. Some | the protocol design, there isn't universal agreement here. Some | |||
| contend that sending the LOGOUT and waiting for the two responses | contend that sending the LOGOUT and waiting for the two responses | |||
| (untagged BYE and tagged OK) is wasteful and unnecessary, and that | (untagged BYE and tagged OK) is wasteful and unnecessary, and that | |||
| the client can simply close the socket. The server should interpret | the client can simply close the socket. The server should interpret | |||
| the closed socket as a log out by the client. The counterargument is | the closed socket as a log out by the client. The counterargument is | |||
| that it's useful from the standpoint of cleanup, problem | that it's useful from the standpoint of cleanup, problem | |||
| determination, and the like, to have an explicit client log out. | determination, and the like, to have an explicit client log out, | |||
| because otherwise there is no way for the server to tell the | ||||
| difference between "closed socket because of log out" and "closed | ||||
| socket because communication was disrupted". If there is a | ||||
| client/server interaction problem, a client which routinely | ||||
| terminates a session by breaking the connection without a LOGOUT will | ||||
| make it much more difficult to determine the problem. | ||||
| Because of this disagreement, server designers must be aware that | Because of this disagreement, server designers must be aware that | |||
| some clients might close the socket without sending a LOGOUT. In any | some clients might close the socket without sending a LOGOUT. In any | |||
| case, whether or not a LOGOUT was sent, the server SHOULD NOT | case, whether or not a LOGOUT was sent, the server SHOULD NOT | |||
| implicitly expunge any messages from the selected mailbox. If a | implicitly expunge any messages from the selected mailbox. If a | |||
| client wants the server to do so, it MUST send a CLOSE or EXPUNGE | client wants the server to do so, it MUST send a CLOSE or EXPUNGE | |||
| command explicitly. | command explicitly. | |||
| When the server wants to sever a connection it's usually due to an | When the server wants to sever a connection it's usually due to an | |||
| inactivity timeout or is because a situation has arisen that has | inactivity timeout or is because a situation has arisen that has | |||
| changed the state of the mail store in a way that the server can not | changed the state of the mail store in a way that the server can not | |||
| communicate to the client. The server SHOULD send an untagged BYE | communicate to the client. The server SHOULD send an untagged BYE | |||
| response to the client and then close the socket. Sending an | response to the client and then close the socket. Sending an | |||
| untagged BYE response before severing allows the server to send a | untagged BYE response before severing allows the server to send a | |||
| human-readable explanation of the problem to the client, which the | human-readable explanation of the problem to the client, which the | |||
| client may then log, display to the user, or both (see section 7.1.5 | client may then log, display to the user, or both (see section 7.1.5 | |||
| of [RFC-2060]). Note that the server MAY also choose to send an | of [RFC-2060]). | |||
| untagged ALERT as well, if it wants to be sure that the client shows | ||||
| the message to the user. The server designer should think carefully, | Internet DRAFT Implementation Recommendations September 1997 | |||
| though, before making a decision that's better left to the client. | ||||
| 3.2. Scaling | 3.2. Scaling | |||
| IMAP4 has many features that allow for scalability, as mail stores | IMAP4 has many features that allow for scalability, as mail stores | |||
| become larger and more numerous. Large numbers of users, mailboxes, | become larger and more numerous. Large numbers of users, mailboxes, | |||
| and messages, and very large messages require thought to handle | and messages, and very large messages require thought to handle | |||
| efficiently. This document will not address the administrative | efficiently. This document will not address the administrative | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| issues involved in large numbers of users, but we will look at the | issues involved in large numbers of users, but we will look at the | |||
| other items. | other items. | |||
| 3.2.1. Flood Control | 3.2.1. Flood Control | |||
| There are three situations when a client can make a request that will | There are three situations when a client can make a request that will | |||
| result in a very large response - too large for the client reasonably | result in a very large response - too large for the client reasonably | |||
| to deal with: there are a great many mailboxes available, there are a | to deal with: there are a great many mailboxes available, there are a | |||
| great many messages in the selected mailbox, or there is a very large | great many messages in the selected mailbox, or there is a very large | |||
| message part. The danger here is that the end user will be stuck | message part. The danger here is that the end user will be stuck | |||
| skipping to change at page 4, line 37 ¶ | skipping to change at page 4, line 43 ¶ | |||
| C: 001 LIST "" * | C: 001 LIST "" * | |||
| to determine the mailbox list. Because of this, clients SHOULD NOT | to determine the mailbox list. Because of this, clients SHOULD NOT | |||
| use an unqualified "*" that way in the LIST command. A safer | use an unqualified "*" that way in the LIST command. A safer | |||
| approach is to list each level of hierarchy individually, allowing | approach is to list each level of hierarchy individually, allowing | |||
| the user to traverse the tree one limb at a time, thus: | the user to traverse the tree one limb at a time, thus: | |||
| C: 001 LIST "" % | C: 001 LIST "" % | |||
| S: * LIST () "/" Banana | S: * LIST () "/" Banana | |||
| S: * LIST ...etc... | S: * LIST ...etc... | |||
| S: 001 OK done | S: 001 OK done | |||
| and hen | and then | |||
| C: 002 LIST "" Banana/% | C: 002 LIST "" Banana/% | |||
| S: * LIST () "/" Banana/Apple | S: * LIST () "/" Banana/Apple | |||
| S: * LIST ...etc... | S: * LIST ...etc... | |||
| S: 002 OK done | S: 002 OK done | |||
| Using this technique the client's user interface can give the user | Using this technique the client's user interface can give the user | |||
| full flexibility without choking on the voluminous reply to "LIST *". | full flexibility without choking on the voluminous reply to "LIST *". | |||
| Of course, it is still possible that the reply to | Of course, it is still possible that the reply to | |||
| C: 005 LIST "" alt.fan.celebrity.% | C: 005 LIST "" alt.fan.celebrity.% | |||
| may be thousands of entries long, and there is, unfortunately, | may be thousands of entries long, and there is, unfortunately, | |||
| nothing the client can do to protect itself from that. This has not | ||||
| yet been a notable problem. | ||||
| Internet DRAFT Implementation Recommendations September 1997 | Internet DRAFT Implementation Recommendations September 1997 | |||
| nothing the client can do to protect itself from that. This has not | ||||
| yet been a notable problem. | ||||
| 3.2.1.2. Fetching the List of Messages | 3.2.1.2. Fetching the List of Messages | |||
| When a client selects a mailbox, it is given a count, in the untagged | When a client selects a mailbox, it is given a count, in the untagged | |||
| EXISTS response, of the messages in the mailbox. This number can be | EXISTS response, of the messages in the mailbox. This number can be | |||
| very large. In such a case it might be unwise to use | very large. In such a case it might be unwise to use | |||
| C: 004 FETCH 1:* ALL | C: 004 FETCH 1:* ALL | |||
| to populate the user's view of the mailbox. A good method to avoid | to populate the user's view of the mailbox. One good method to avoid | |||
| problems with this is to batch the requests, thus: | problems with this is to batch the requests, thus: | |||
| C: 004 FETCH 1:50 ALL | C: 004 FETCH 1:50 ALL | |||
| S: * 1 FETCH ...etc... | S: * 1 FETCH ...etc... | |||
| S: 004 OK done | S: 004 OK done | |||
| C: 005 FETCH 51:100 ALL | C: 005 FETCH 51:100 ALL | |||
| S: * 51 FETCH ...etc... | S: * 51 FETCH ...etc... | |||
| S: 005 OK done | S: 005 OK done | |||
| C: 006 FETCH 101:150 ALL | C: 006 FETCH 101:150 ALL | |||
| ...etc... | ...etc... | |||
| Using this method, another command, such as "FETCH 6 BODY[1]" can be | Using this method, another command, such as "FETCH 6 BODY[1]" can be | |||
| inserted as necessary, and the client will not have its access to the | inserted as necessary, and the client will not have its access to the | |||
| server blocked by a storm of FETCH replies. (Such a method could be | server blocked by a storm of FETCH replies. (Such a method could be | |||
| reversed to fetch the LAST 50 messages first, then the 50 prior to | reversed to fetch the LAST 50 messages first, then the 50 prior to | |||
| that, and so on.) | that, and so on.) | |||
| As a smart extension of this, a well designed client, prepared for | ||||
| very large mailboxes, will not fetch all message data AT ALL. | ||||
| Rather, the client will populate the user's view only as the user | ||||
| sees it, possibly pre-fetching selected information, and only | ||||
| fetching other information as the user scrolls to it. For example, | ||||
| to select only those messages beginning with the first unseen one: | ||||
| C: 003 SELECT INBOX | ||||
| S: * 10000 EXISTS | ||||
| S: * 80 RECENT | ||||
| S: * FLAGS (\Answered \Flagged \Deleted \Draft \Seen) | ||||
| S: * OK [UIDVALIDITY 824708485] UID validity status | ||||
| S: * OK [UNSEEN 9921] First unseen message | ||||
| S: 003 OK [READ-WRITE] SELECT completed | ||||
| C: 004 FETCH 9921:* ALL | ||||
| ... etc... | ||||
| If the server does not return an OK [UNSEEN] response, the client may | ||||
| use SEARCH UNSEEN to obtain that value. | ||||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| 3.2.1.3. Fetching a Large Body Part | 3.2.1.3. Fetching a Large Body Part | |||
| The issue here is similar to the one for a list of messages. In the | The issue here is similar to the one for a list of messages. In the | |||
| BODYSTRUCTURE response the client knows the size, in bytes, of the | BODYSTRUCTURE response the client knows the size, in bytes, of the | |||
| body part it plans to fetch. Suppose this is a 70 MB video clip. | body part it plans to fetch. Suppose this is a 70 MB video clip. | |||
| The client can use partial fetches to retrieve the body part in | The client can use partial fetches to retrieve the body part in | |||
| pieces, avoiding the problem of an uninterruptible 70 MB literal | pieces, avoiding the problem of an uninterruptible 70 MB literal | |||
| coming back from the server: | coming back from the server: | |||
| C: 022 FETCH 3 BODY[1]<0.20000> | C: 022 FETCH 3 BODY[1]<0.20000> | |||
| skipping to change at page 6, line 4 ¶ | skipping to change at page 6, line 30 ¶ | |||
| C: 023 FETCH 3 BODY[1]<20001.20000> | C: 023 FETCH 3 BODY[1]<20001.20000> | |||
| S: * 3 FETCH (BODY[1]<20001> {20000} | S: * 3 FETCH (BODY[1]<20001> {20000} | |||
| S: ...data...) | S: ...data...) | |||
| S: 023 OK done | S: 023 OK done | |||
| C: 024 FETCH 3 BODY[1]<40001.20000> | C: 024 FETCH 3 BODY[1]<40001.20000> | |||
| ...etc... | ...etc... | |||
| 3.2.1.4. BODYSTRUCTURE vs. Entire Messages | 3.2.1.4. BODYSTRUCTURE vs. Entire Messages | |||
| Because FETCH BODYSTRUCTURE is necessary in order to determine the | Because FETCH BODYSTRUCTURE is necessary in order to determine the | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| number of body parts, and, thus, whether a message has "attachments", | number of body parts, and, thus, whether a message has "attachments", | |||
| clients often use FETCH FULL as their normal method of populating the | clients often use FETCH FULL as their normal method of populating the | |||
| user's view of a mailbox. The benefit is that the client can display | user's view of a mailbox. The benefit is that the client can display | |||
| a paperclip icon or some such indication along with the normal | a paperclip icon or some such indication along with the normal | |||
| message summary. However, this comes at a significant cost with some | message summary. However, this comes at a significant cost with some | |||
| server configurations. The parsing needed to generate the FETCH | server configurations. The parsing needed to generate the FETCH | |||
| BODYSTRUCTURE response may be time-consuming compared with that | BODYSTRUCTURE response may be time-consuming compared with that | |||
| needed for FETCH ENVELOPE. The client developer should consider this | needed for FETCH ENVELOPE. The client developer should consider this | |||
| issue when deciding whether the ability to add a paperclip icon is | issue when deciding whether the ability to add a paperclip icon is | |||
| worth the tradeoff in performance, especially with large mailboxes. | worth the tradeoff in performance, especially with large mailboxes. | |||
| skipping to change at page 6, line 31 ¶ | skipping to change at page 7, line 5 ¶ | |||
| client slightly more flexibility in some areas (access, for instance, | client slightly more flexibility in some areas (access, for instance, | |||
| to header fields that aren't returned in the BODYSTRUCTURE and | to header fields that aren't returned in the BODYSTRUCTURE and | |||
| ENVELOPE responses), but it can cause severe performance problems by | ENVELOPE responses), but it can cause severe performance problems by | |||
| forcing the transfer of all body parts when the user might only want | forcing the transfer of all body parts when the user might only want | |||
| to see some of them - a user logged on by modem and reading a small | to see some of them - a user logged on by modem and reading a small | |||
| text message with a large ZIP file attached may prefer to read the | text message with a large ZIP file attached may prefer to read the | |||
| text only and save the ZIP file for later. Therefore, a client | text only and save the ZIP file for later. Therefore, a client | |||
| SHOULD NOT normally retrieve entire messages and SHOULD retrieve | SHOULD NOT normally retrieve entire messages and SHOULD retrieve | |||
| message body parts selectively. | message body parts selectively. | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| 3.2.2. Subscriptions | 3.2.2. Subscriptions | |||
| The client isn't the only entity that can get flooded: the end user, | The client isn't the only entity that can get flooded: the end user, | |||
| too, may need some flood control. The IMAP4 protocol provides such | too, may need some flood control. The IMAP4 protocol provides such | |||
| control in the form of subscriptions. Most servers support the | control in the form of subscriptions. Most servers support the | |||
| SUBSCRIBE, UNSUBSCRIBE, and LSUB commands, and many users choose to | SUBSCRIBE, UNSUBSCRIBE, and LSUB commands, and many users choose to | |||
| narrow down a large list of available mailboxes by subscribing to the | narrow down a large list of available mailboxes by subscribing to the | |||
| ones that they usually want to see. Clients, with this in mind, | ones that they usually want to see. Clients, with this in mind, | |||
| SHOULD give the user a way to see only subscribed mailboxes. A | SHOULD give the user a way to see only subscribed mailboxes. A | |||
| client that never uses the LSUB command takes a significant usability | client that never uses the LSUB command takes a significant usability | |||
| skipping to change at page 7, line 4 ¶ | skipping to change at page 7, line 30 ¶ | |||
| 3.2.3. Searching | 3.2.3. Searching | |||
| IMAP SEARCH commands can become particularly troublesome (that is, | IMAP SEARCH commands can become particularly troublesome (that is, | |||
| slow) on mailboxes containing a large number of messages. So let's | slow) on mailboxes containing a large number of messages. So let's | |||
| put a few things in perspective in that regard. | put a few things in perspective in that regard. | |||
| The flag searches SHOULD be fast. The flag searches (ALL, [UN]SEEN, | The flag searches SHOULD be fast. The flag searches (ALL, [UN]SEEN, | |||
| [UN]ANSWERED, [UN]DELETED, [UN]DRAFT, [UN]FLAGGED, NEW, OLD, RECENT) | [UN]ANSWERED, [UN]DELETED, [UN]DRAFT, [UN]FLAGGED, NEW, OLD, RECENT) | |||
| are known to be used by clients for the client's own use (for | are known to be used by clients for the client's own use (for | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| instance, some clients use "SEARCH UNSEEN" to find unseen mail and | instance, some clients use "SEARCH UNSEEN" to find unseen mail and | |||
| "SEARCH DELETED" to warn the user before expunging messages). | "SEARCH DELETED" to warn the user before expunging messages). | |||
| Other searches, particularly the text searches (HEADER, TEXT, BODY) | Other searches, particularly the text searches (HEADER, TEXT, BODY) | |||
| are initiated by the user, rather than by the client itself, and | are initiated by the user, rather than by the client itself, and | |||
| somewhat slower performance can be tolerated, since the user is aware | somewhat slower performance can be tolerated, since the user is aware | |||
| that the search is being done (and is probably aware that it might be | that the search is being done (and is probably aware that it might be | |||
| time-consuming). | time-consuming). | |||
| The client MAY allow other commands to be sent to the server while a | The client MAY allow other commands to be sent to the server while a | |||
| skipping to change at page 7, line 32 ¶ | skipping to change at page 8, line 4 ¶ | |||
| Another word about text searches: some servers, built on database | Another word about text searches: some servers, built on database | |||
| back-ends with indexed search capabilities, may return search results | back-ends with indexed search capabilities, may return search results | |||
| that do not match the IMAP spec's "case-insensitive substring" | that do not match the IMAP spec's "case-insensitive substring" | |||
| requirements. While these servers are in violation of the protocol, | requirements. While these servers are in violation of the protocol, | |||
| there is little harm in the violation as long as the search results | there is little harm in the violation as long as the search results | |||
| are used only to response to a user's request. Still, developers of | are used only to response to a user's request. Still, developers of | |||
| such servers should be aware that they ARE violating the protocol, | such servers should be aware that they ARE violating the protocol, | |||
| should think carefully about that behaviour, and MUST be certain that | should think carefully about that behaviour, and MUST be certain that | |||
| their servers respond accurately to the flag searches for the reasons | their servers respond accurately to the flag searches for the reasons | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| outlined above. | outlined above. | |||
| 3.3. Miscellaneous Protocol Considerations | 3.3 Avoiding Invalid Requests | |||
| IMAP4 provides ways for a server to tell a client in advance what is | ||||
| and isn't permitted in some circumstances. Clients SHOULD use these | ||||
| features to avoid sending requests that a well designed client would | ||||
| know to be invalid. This section explains this in more detail. | ||||
| 3.3.1. The CAPABILITY Command | ||||
| All IMAP4 clients SHOULD use the CAPABILITY command to determine what | ||||
| version of IMAP and what optional features a server supports. The | ||||
| client SHOULD NOT send IMAP4rev1 commands and arguments to a server | ||||
| that does not advertize IMAP4rev1 in its CAPABILITY response. | ||||
| Similarly, the client SHOULD NOT send IMAP4 commands that no longer | ||||
| exist in IMAP4rev1 to a server that does not advertize IMAP4 in its | ||||
| CAPABILITY response. An IMAP4rev1 server is NOT required to support | ||||
| obsolete IMAP4 or IMAP2bis commands (though some do; do not let this | ||||
| fact lull you into thinking that it's valid to send such commands to | ||||
| an IMAP4rev1 server). | ||||
| A client SHOULD NOT send commands to probe for the existance of | ||||
| certain extensions. All standard and standards-track extensions | ||||
| include CAPABILITY tokens indicating their presense. All private and | ||||
| experimental extensions SHOULD do the same, and clients that take | ||||
| advantage of them SHOULD use the CAPABILITY response to determine | ||||
| whether they may be used or not. | ||||
| 3.3.2. Don't Do What the Server Says You Can't | ||||
| In many cases, the server, in response to a command, will tell the | ||||
| client something about what can and can't be done with a particular | ||||
| mailbox. The client SHOULD pay attention to this information and | ||||
| SHOULD NOT try to do things that it's been told it can't do. | ||||
| Examples: | ||||
| * Do not try to SELECT a mailbox that has the \Noselect flag set. | ||||
| * Do not try to CREATE a sub-mailbox in a mailbox that has the | ||||
| \Noinferiors flag set. | ||||
| * Do not respond to a failing COPY or APPEND command by trying to | ||||
| CREATE the target mailbox if the server does not respond with a | ||||
| [TRYCREATE] response code. | ||||
| * Do not try to expunge a mailbox that has been selected with the | ||||
| [READ-ONLY] response code. | ||||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| 3.4. Miscellaneous Protocol Considerations | ||||
| We describe here a number of important protocol-related issues, the | We describe here a number of important protocol-related issues, the | |||
| misunderstanding of which has caused significant interoperability | misunderstanding of which has caused significant interoperability | |||
| problems in IMAP4 implementations. One general item is that every | problems in IMAP4 implementations. One general item is that every | |||
| implementer should be certain to take note of and to understand | implementer should be certain to take note of and to understand | |||
| section 2.2.2 and the preamble to section 7 of the IMAP4rev1 spec | section 2.2.2 and the preamble to section 7 of the IMAP4rev1 spec | |||
| [RFC-2060]. | [RFC-2060]. | |||
| 3.3.1. UIDs and UIDVALIDITY | 3.4.1. Well Formed Protocol | |||
| We cannot stress enough the importance of adhering strictly to the | ||||
| protocol grammar. The specification of the protocol is quite rigid; | ||||
| do not assume that you can insert blank space for "readability" if | ||||
| none is called for. Keep in mind that there are parsers out there | ||||
| that will crash if there are protocol errors. There are clients that | ||||
| will report every parser burp to the user. And in any case, | ||||
| information that cannot be parsed is information that is lost. Be | ||||
| careful in your protocol generation. And see "A Word About Testing", | ||||
| below. | ||||
| In particular, note that the string in the INTERNALDATE response is | ||||
| NOT an RFC-822 date string - that is, it is not in the same format as | ||||
| the first string in the ENVELOPE response. Since most clients will, | ||||
| in fact, accept an RFC-822 date string in the INTERNALDATE response, | ||||
| it's easy to miss this in your interoperability testing. But it will | ||||
| cause a problem with some client, so be sure to generate the correct | ||||
| string for this field. | ||||
| 3.4.2. Special Characters | ||||
| Certain characters, currently the double-quote and the backslash, may | ||||
| not be sent as they are inside a quoted string. These characters | ||||
| MUST be preceded by the escape character if they are in a quoted | ||||
| string, or else the string must be sent as a literal. Both clients | ||||
| and servers MUST handle this, both on output (they must send these | ||||
| characters properly) and on input (they must be able to receive | ||||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| escaped characters in quoted strings). Example: | ||||
| C: 001 LIST "" % | ||||
| S: * LIST () "" INBOX | ||||
| S: * LIST () "\\" TEST | ||||
| S: * LIST () "\\" {12} | ||||
| S: "My" mailbox | ||||
| S: 001 OK done | ||||
| C: 002 LIST "" "\"My\" mailbox\\%" | ||||
| S: * LIST () "\\" {17} | ||||
| S: "My" mailbox\Junk | ||||
| S: 002 OK done | ||||
| Note that in the example the server sent the hierarchy delimiter as | ||||
| an escaped character in the quoted string and sent the mailbox name | ||||
| containing imbedded double-quotes as a literal. The client used only | ||||
| quoted strings, escaping both the backslash and the double-quote | ||||
| characters. | ||||
| The CR and LF characters may be sent ONLY in literals; they are not | ||||
| allowed, even if escaped, inside quoted strings. | ||||
| 3.4.3. UIDs and UIDVALIDITY | ||||
| Servers that support existing back-end mail stores often have no good | Servers that support existing back-end mail stores often have no good | |||
| place to save UIDs for messages. Often the existing mail store will | place to save UIDs for messages. Often the existing mail store will | |||
| not have the concept of UIDs in the sense that IMAP has: strictly | not have the concept of UIDs in the sense that IMAP has: strictly | |||
| increasing, never re-issued, 32-bit integers. Some servers solve | increasing, never re-issued, 32-bit integers. Some servers solve | |||
| this by storing the UIDs in a place that's accessible to end users, | this by storing the UIDs in a place that's accessible to end users, | |||
| allowing for the possibility that the users will delete them. Others | allowing for the possibility that the users will delete them. Others | |||
| solve it by re-assigning UIDs every time a mailbox is selected. | solve it by re-assigning UIDs every time a mailbox is selected. | |||
| The server SHOULD maintain UIDs permanently for all messages if it | The server SHOULD maintain UIDs permanently for all messages if it | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| can. If that's not possible, the server MUST change the UIDVALIDITY | can. If that's not possible, the server MUST change the UIDVALIDITY | |||
| value for the mailbox whenever any of the UIDs may have become | value for the mailbox whenever any of the UIDs may have become | |||
| invalid. Clients MUST recognize that the UIDVALIDITY has changed and | invalid. Clients MUST recognize that the UIDVALIDITY has changed and | |||
| MUST respond to that condition by throwing away any information that | MUST respond to that condition by throwing away any information that | |||
| they have saved about UIDs in that mailbox. There have been many | they have saved about UIDs in that mailbox. There have been many | |||
| problems in this area when clients have failed to do this; in the | problems in this area when clients have failed to do this; in the | |||
| worst case it will result in loss of mail when a client deletes the | worst case it will result in loss of mail when a client deletes the | |||
| wrong piece of mail by using a stale UID. | wrong piece of mail by using a stale UID. | |||
| It seems to be a common myth that "the UIDVALIDITY and the UID, taken | It seems to be a common myth that "the UIDVALIDITY and the UID, taken | |||
| together, form a 64-bit identifier that uniquely identifies a message | together, form a 64-bit identifier that uniquely identifies a message | |||
| on a server". This is absolutely NOT TRUE. There is no assurance | on a server". This is absolutely NOT TRUE. There is no assurance | |||
| that the UIDVALIDITY values of two mailboxes be different, so the | that the UIDVALIDITY values of two mailboxes be different, so the | |||
| UIDVALIDITY in no way identifies a mailbox. The ONLY purpose of | UIDVALIDITY in no way identifies a mailbox. The ONLY purpose of | |||
| UIDVALIDITY is, as its name indicates, to give the client a way to | UIDVALIDITY is, as its name indicates, to give the client a way to | |||
| check the validity of the UIDs it has cached. | ||||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| check the validity of the UIDs it has cached. While it is a valid | ||||
| implementation choice to put these values together to make a 64-bit | ||||
| identifier for the message, the important concept here is that UIDs | ||||
| are not unique between mailboxes; they are only unique WITHIN a given | ||||
| mailbox. | ||||
| Under extreme circumstances (and this is extreme, indeed), the server | Under extreme circumstances (and this is extreme, indeed), the server | |||
| may have to invalidate UIDs while a mailbox is in use by a client - | may have to invalidate UIDs while a mailbox is in use by a client - | |||
| that is, the UIDs that the client knows about in its active mailbox | that is, the UIDs that the client knows about in its active mailbox | |||
| are no longer valid. In that case, since there is no way to | are no longer valid. In that case, the server MUST immediately | |||
| communicate this to the client (and since this could result in a loss | change the UIDVALIDITY and MUST communicate this to the client. The | |||
| of mail, should the client use the old UIDs to refer to the wrong | server MAY do this by sending an unsolicited UIDVALIDITY message, in | |||
| messages), the server MUST force the client to re-select the mailbox, | the same form as in response to the SELECT command. Clients MUST be | |||
| at which time it will obtain a new UIDVALIDITY value. To do this, | prepared to handle such a message and the possibly coincident failure | |||
| the server closes this client session (see "Severed Connections" | of the command in process. For example: | |||
| above) and the client then reconnects and gets back in synch. | ||||
| 3.3.2. FETCH Responses | C: 032 UID STORE 382 +Flags.silent \Deleted | |||
| S: * OK [UIDVALIDITY 12345] New UIDVALIDITY value! | ||||
| S: 032 NO UID command rejeced because UIDVALIDITY changed! | ||||
| C: ...invalidates local information and re-fetches... | ||||
| C: 033 FETCH 1:* UID | ||||
| ...etc... | ||||
| Alternatively, some servers force the client to re-select the | ||||
| mailbox, at which time it will obtain a new UIDVALIDITY value. To do | ||||
| this, the server closes this client session (see "Severed | ||||
| Connections" above) and the client then reconnects and gets back in | ||||
| synch. Clients MUST be prepared for either of these behaviours. | ||||
| 3.4.4. FETCH Responses | ||||
| When a client asks for certain information in a FETCH command, the | When a client asks for certain information in a FETCH command, the | |||
| server MAY return the requested information in any order, not | server MAY return the requested information in any order, not | |||
| necessarily in the order that it was requested. Further, the server | necessarily in the order that it was requested. Further, the server | |||
| MAY return the information in separate FETCH responses and MAY also | MAY return the information in separate FETCH responses and MAY also | |||
| return information that was not explicitly requested (to reflect to | return information that was not explicitly requested (to reflect to | |||
| the client changes in the state of the subject message). Some | the client changes in the state of the subject message). Some | |||
| examples: | examples: | |||
| C: 001 FETCH 1 UID FLAGS INTERNALDATE | C: 001 FETCH 1 UID FLAGS INTERNALDATE | |||
| skipping to change at page 9, line 34 ¶ | skipping to change at page 12, line 34 ¶ | |||
| FETCH response at any time and should use that information to update | FETCH response at any time and should use that information to update | |||
| its local information about the message to which the FETCH response | its local information about the message to which the FETCH response | |||
| refers. A client MUST NOT assume that any FETCH responses will come | refers. A client MUST NOT assume that any FETCH responses will come | |||
| in any particular order, or even that any will come at all. If after | in any particular order, or even that any will come at all. If after | |||
| receiving the tagged response for a FETCH command the client finds | receiving the tagged response for a FETCH command the client finds | |||
| that it did not get all of the information requested, the client | that it did not get all of the information requested, the client | |||
| SHOULD send a NOOP command to the server to ensure that the server | SHOULD send a NOOP command to the server to ensure that the server | |||
| has an opportunity to send any pending EXPUNGE responses to the | has an opportunity to send any pending EXPUNGE responses to the | |||
| client (see [RFC-2180]). | client (see [RFC-2180]). | |||
| 3.3.3. RFC822.SIZE | 3.4.5. RFC822.SIZE | |||
| Some back-end mail stores keep the mail in a canonical form, rather | Some back-end mail stores keep the mail in a canonical form, rather | |||
| than retaining the original MIME format of the messages. This means | than retaining the original MIME format of the messages. This means | |||
| that the server must reassemble the message to produce a MIME stream | that the server must reassemble the message to produce a MIME stream | |||
| when a client does a fetch such as RFC822 or BODY[], requesting the | when a client does a fetch such as RFC822 or BODY[], requesting the | |||
| entire message. It also may mean that the server has no convenient | entire message. It also may mean that the server has no convenient | |||
| way to know the RFC822.SIZE of the message. Often, such a server | way to know the RFC822.SIZE of the message. Often, such a server | |||
| will actually have to build the MIME stream to compute the size, only | will actually have to build the MIME stream to compute the size, only | |||
| to throw the stream away and report the size to the client. | to throw the stream away and report the size to the client. | |||
| When this is the case, some servers have chosen to estimate the size, | When this is the case, some servers have chosen to estimate the size, | |||
| rather than to compute it precisely. Such an estimate allows the | rather than to compute it precisely. Such an estimate allows the | |||
| client to display an approximate size to the user and to use the | client to display an approximate size to the user and to use the | |||
| estimate in flood control considerations (q.v.), but requires that | estimate in flood control considerations (q.v.), but requires that | |||
| the client not use the size for things such as allocation of buffers, | the client not use the size for things such as allocation of buffers, | |||
| because those buffers might then be too small to hold the actual MIME | because those buffers might then be too small to hold the actual MIME | |||
| stream. Instead, use the size that's returned in the literal when | stream. Instead, a client SHOULD use the size that's returned in the | |||
| you fetch the data. | literal when you fetch the data. | |||
| The protocol requires that the RFC822.SIZE value returned by the | The protocol requires that the RFC822.SIZE value returned by the | |||
| Internet DRAFT Implementation Recommendations September 1997 | Internet DRAFT Implementation Recommendations September 1997 | |||
| server be EXACT. Estimating the size is a protocol violation, and | server be EXACT. Estimating the size is a protocol violation, and | |||
| server designers must be aware that, despite the performance savings | server designers must be aware that, despite the performance savings | |||
| they might realize in using an estimate, this practice will cause | they might realize in using an estimate, this practice will cause | |||
| some clients to fail in various ways. If possible, the server SHOULD | some clients to fail in various ways. If possible, the server SHOULD | |||
| compute the RFC822.SIZE for a particular message once, and then save | compute the RFC822.SIZE for a particular message once, and then save | |||
| it for later retrieval. If that's not possible, the server MUST | it for later retrieval. If that's not possible, the server MUST | |||
| compute the value exactly every time. Incorrect estimates do cause | compute the value exactly every time. Incorrect estimates do cause | |||
| severe interoperability problems with some clients. | severe interoperability problems with some clients. | |||
| 3.3.4. Expunged Messages | 3.4.6. Expunged Messages | |||
| If the server allows multiple connections to the same mailbox, it is | If the server allows multiple connections to the same mailbox, it is | |||
| often possible for messages to be expunged in one client unbeknownst | often possible for messages to be expunged in one client unbeknownst | |||
| to another client. Since the server is not allowed to tell the | to another client. Since the server is not allowed to tell the | |||
| client about these expunged messages in response to a FETCH command, | client about these expunged messages in response to a FETCH command, | |||
| the server may have to deal with the issue of how to return | the server may have to deal with the issue of how to return | |||
| information about an expunged message. There was extensive | information about an expunged message. There was extensive | |||
| discussion about this issue, and the results of that discussion are | discussion about this issue, and the results of that discussion are | |||
| summarized in [RFC-2180]. See that reference for a detailed | summarized in [RFC-2180]. See that reference for a detailed | |||
| explanation and for recommendations. | explanation and for recommendations. | |||
| 3.3.5. The Namespace Issue | 3.4.7. The Namespace Issue | |||
| Namespaces are a very muddy area in IMAP4 implementation right now | Namespaces are a very muddy area in IMAP4 implementation right now | |||
| (see [NAMESPACE] for a proposal to clear the water a bit). Until the | (see [NAMESPACE] for a proposal to clear the water a bit). Until the | |||
| issue is resolved, the important thing for client developers to | issue is resolved, the important thing for client developers to | |||
| understand is that some servers provide access through IMAP to more | understand is that some servers provide access through IMAP to more | |||
| than just the user's personal mailboxes, and, in fact, the user's | than just the user's personal mailboxes, and, in fact, the user's | |||
| personal mailboxes may be "hidden" somewhere in the user's default | personal mailboxes may be "hidden" somewhere in the user's default | |||
| hierarchy. The client, therefore, SHOULD provide a setting wherein | hierarchy. The client, therefore, SHOULD provide a setting wherein | |||
| the user can specify a prefix to be used when accessing mailboxes. | the user can specify a prefix to be used when accessing mailboxes. | |||
| If the user's mailboxes are all in "~/mail/", for instance, then the | If the user's mailboxes are all in "~/mail/", for instance, then the | |||
| user can put that string in the prefix. The client would then put | user can put that string in the prefix. The client would then put | |||
| the prefix in front of any name pattern in the LIST and LSUB | the prefix in front of any name pattern in the LIST and LSUB | |||
| commands: | commands: | |||
| C: 001 LIST "" ~/mail/% | C: 001 LIST "" ~/mail/% | |||
| (See also "Reference Names in the LIST Command" below.) | (See also "Reference Names in the LIST Command" below.) | |||
| 3.3.6. Creating Special-Use Mailboxes | 3.4.8. Creating Special-Use Mailboxes | |||
| It may seem at first that this is part of the namespace issue; it is | It may seem at first that this is part of the namespace issue; it is | |||
| not, and is only indirectly related to it. A number of clients like | not, and is only indirectly related to it. A number of clients like | |||
| to create special-use mailboxes with particular names. Most | to create special-use mailboxes with particular names. Most | |||
| commonly, clients with a "trash folder" model of message deletion | commonly, clients with a "trash folder" model of message deletion | |||
| want to create a mailbox with the name "Trash" or "Deleted". Some | want to create a mailbox with the name "Trash" or "Deleted". Some | |||
| clients want to create a "Drafts" mailbox, an "Outbox" mailbox, or a | clients want to create a "Drafts" mailbox, an "Outbox" mailbox, or a | |||
| Internet DRAFT Implementation Recommendations September 1997 | Internet DRAFT Implementation Recommendations September 1997 | |||
| skipping to change at page 11, line 23 ¶ | skipping to change at page 14, line 23 ¶ | |||
| 2. there is no guarantee that the server will allow the creation of | 2. there is no guarantee that the server will allow the creation of | |||
| the desired mailbox. | the desired mailbox. | |||
| The client developer is, therefore, well advised to consider | The client developer is, therefore, well advised to consider | |||
| carefully the creation of any special-use mailboxes on the server, | carefully the creation of any special-use mailboxes on the server, | |||
| and, further, the client MUST NOT require such mailbox creation - | and, further, the client MUST NOT require such mailbox creation - | |||
| that is, if you do decide to do this, you MUST handle gracefully the | that is, if you do decide to do this, you MUST handle gracefully the | |||
| failure of the CREATE command and behave reasonably when your | failure of the CREATE command and behave reasonably when your | |||
| special-use mailboxes do not exist and can not be created. | special-use mailboxes do not exist and can not be created. | |||
| 3.3.7. Reference Names in the LIST Command | In addition, the client developer SHOULD provide a convenient way for | |||
| the user to select the names for any special-use mailboxes, allowing | ||||
| the user to make these names the same in all clients s/he uses and to | ||||
| put them where s/he wants them. | ||||
| 3.4.9. Reference Names in the LIST Command | ||||
| Many implementers of both clients and servers are confused by the | Many implementers of both clients and servers are confused by the | |||
| "reference name" on the LIST command. The reference name is intended | "reference name" on the LIST command. The reference name is intended | |||
| to be used in much the way a "cd" (change directory) command is used | to be used in much the way a "cd" (change directory) command is used | |||
| on Unix, PC DOS, Windows, and OS/2 systems. That is, the mailbox | on Unix, PC DOS, Windows, and OS/2 systems. That is, the mailbox | |||
| name is interpreted in much the same way as a file of that name would | name is interpreted in much the same way as a file of that name would | |||
| be found if one had done a "cd" command into the directory specified | be found if one had done a "cd" command into the directory specified | |||
| by the reference name. For example, in Unix we have the following: | by the reference name. For example, in Unix we have the following: | |||
| > cd /u/jones/junk | > cd /u/jones/junk | |||
| skipping to change at page 11, line 51 ¶ | skipping to change at page 15, line 5 ¶ | |||
| in those configurations. Second, while some IMAP servers expose the | in those configurations. Second, while some IMAP servers expose the | |||
| underlying file system to the clients, others allow access only to | underlying file system to the clients, others allow access only to | |||
| the user's personal mailboxes, or to some other limited set of files, | the user's personal mailboxes, or to some other limited set of files, | |||
| making such file-system-like semantics less meaningful. Third, | making such file-system-like semantics less meaningful. Third, | |||
| because the IMAP spec leaves the interpretation of the reference name | because the IMAP spec leaves the interpretation of the reference name | |||
| as "implementation-dependent", the various server implementations | as "implementation-dependent", the various server implementations | |||
| handle it in vastly differing ways, and fourth, many implementers | handle it in vastly differing ways, and fourth, many implementers | |||
| simply do not understand it and misuse it, do not use it, or ignore | simply do not understand it and misuse it, do not use it, or ignore | |||
| it as a result. | it as a result. | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| The following statement gets somewhat into the religious issues that | The following statement gets somewhat into the religious issues that | |||
| we've tried to avoid scrupulously here; so be it: because of the | we've tried to avoid scrupulously here; so be it: because of the | |||
| confusion around the reference name, its use by a client is a | confusion around the reference name, its use by a client is a | |||
| dangerous thing, prone to result in interoperability problems. There | dangerous thing, prone to result in interoperability problems. There | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| are servers that interpret it as originally intended; there are | are servers that interpret it as originally intended; there are | |||
| servers that ignore it completely; there are servers that simply | servers that ignore it completely; there are servers that simply | |||
| prepend it to the mailbox name (with or without inserting a hierarchy | prepend it to the mailbox name (with or without inserting a hierarchy | |||
| delimiter in between). Because a client can't know which of these | delimiter in between). Because a client can't know which of these | |||
| four behaviours to expect, the safest route is to leave it empty and | four behaviours to expect, a client SHOULD NOT use a reference name | |||
| put the full mailbox name pattern in the mailbox name argument. | itself, expecting a particular server behavior. However, a client | |||
| SHOULD permit a USER, by configuration, to use a reference name. | ||||
| There is in no way universal agreement about the use or non-use of | There is in no way universal agreement about the use or non-use of | |||
| the reference name. The last words here are, "Be aware." | the reference name. The last words here are, "Be aware." | |||
| 3.4. A Word About Testing | 3.5. A Word About Testing | |||
| Since the whole point of IMAP is interoperability, and since | Since the whole point of IMAP is interoperability, and since | |||
| interoperability can not be tested in a vacuum, the final | interoperability can not be tested in a vacuum, the final | |||
| recommendation of this treatise is, "Test against EVERYTHING." Test | recommendation of this treatise is, "Test against EVERYTHING." Test | |||
| your client against every server you can get an account on. Test | your client against every server you can get an account on. Test | |||
| your server with every client you can get your hands on. Many | your server with every client you can get your hands on. Many | |||
| clients make limited test versions available on the Web for the | clients make limited test versions available on the Web for the | |||
| downloading. Many server owners will give serious client developers | downloading. Many server owners will give serious client developers | |||
| guest accounts for testing. Contact them and ask. NEVER assume that | guest accounts for testing. Contact them and ask. NEVER assume that | |||
| because your client works with one or two servers, or because your | because your client works with one or two servers, or because your | |||
| skipping to change at page 12, line 41 ¶ | skipping to change at page 15, line 46 ¶ | |||
| In particular, in addition to everything else, be sure to test | In particular, in addition to everything else, be sure to test | |||
| against the reference implementations: the PINE client, the | against the reference implementations: the PINE client, the | |||
| University of Washington server, and the Cyrus server. | University of Washington server, and the Cyrus server. | |||
| See the following URLs on the web for more information here: | See the following URLs on the web for more information here: | |||
| IMAP Products and Sources: http://www.imap.org/products.html | IMAP Products and Sources: http://www.imap.org/products.html | |||
| IMC MailConnect: http://www.imc.org/imc-mailconnect | IMC MailConnect: http://www.imc.org/imc-mailconnect | |||
| 4. Security Considerations | 4. Security Considerations | |||
| This document describes behavior of servers that use the IMAP4 | This document describes behaviour of clients and servers that use the | |||
| protocol, and as such, has the same security considerations as | IMAP4 protocol, and as such, has the same security considerations as | |||
| described in [RFC-2060]. | described in [RFC-2060]. | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| 5. References | 5. References | |||
| [RFC-2060], Crispin, M., "Internet Message Access Protocol - Version | [RFC-2060], Crispin, M., "Internet Message Access Protocol - Version | |||
| 4rev1", RFC 2060, University of Washington, December 1996. | 4rev1", RFC 2060, University of Washington, December 1996. | |||
| [RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate | [RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", RFC 2119, Harvard University, March 1997. | Requirement Levels", RFC 2119, Harvard University, March 1997. | |||
| Internet DRAFT Implementation Recommendations September 1997 | ||||
| [RFC-2180], Gahrns, M., "IMAP4 Multi-Accessed Mailbox Practice", RFC | [RFC-2180], Gahrns, M., "IMAP4 Multi-Accessed Mailbox Practice", RFC | |||
| 2180, Microsoft, July 1997. | 2180, Microsoft, July 1997. | |||
| [NAMESPACE], Gahrns, M. & Newman, C., "IMAP4 Namespace", draft | [NAMESPACE], Gahrns, M. & Newman, C., "IMAP4 Namespace", draft | |||
| document <draft-gahrns-imap-namespace-01.txt>, June 1997. | document <draft-gahrns-imap-namespace-01.txt>, June 1997. | |||
| 6. Acknowledgments | 6. Acknowledgments | |||
| To be completed... | To be completed... | |||
| This document is the result of discussions on the IMAP4 mailing list | ||||
| and is meant to reflect consensus of this group. In particular, Mark | ||||
| Crispin was an active participant in the discussions or made | ||||
| suggestions to this document. | ||||
| 7. Author's Address | 7. Author's Address | |||
| Barry Leiba | Barry Leiba | |||
| IBM T.J. Watson Research Center | IBM T.J. Watson Research Center | |||
| 30 Saw Mill River Road | 30 Saw Mill River Road | |||
| Hawthorne, NY 10532 | Hawthorne, NY 10532 | |||
| Phone: 1-914-784-7941 | Phone: 1-914-784-7941 | |||
| Email: leiba@watson.ibm.com | Email: leiba@watson.ibm.com | |||
| End of changes. 39 change blocks. | ||||
| 63 lines changed or deleted | 204 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||