On Thu, 14 Nov 2002 10:38:39 +1300, David Harris wrote: > What is the proper action to take when a client issues a SUBSCRIBE > command with a parameter that already appears in the subscription list? > Should a duplicate be created, or should the existing entry be removed > from the subscription list?
The IMAP protocol takes no position on whether or not duplicate entries are permitted in the subscription list. I don't think that it should. There is a wide range of behaviors in IMAP that are permitted (by virtue of not being explicitly prohibited), but are "silly" for one reason or another. Duplicate subscription seems to me to be such a "silly" behavior; it is generally avoidable, and can not be reliably used to accomplish anything. I don't think that the specification should be weighed down further with details on how to respond to silly behavior; as long as the response can be justified by the specification, it is alright. It is clear that if a SUBSCRIBE command returns a tagged OK, it must have added the name to the subscription list: [RFC 2060, section 6.3.6] The SUBSCRIBE command adds the specified mailbox name to the server's set of "active" or "subscribed" mailboxes as returned by the LSUB command. This command returns a tagged OK response only if the subscription is successful. There is nothing to suggest "removing" or "replacing" any existing entry, although it seems that Cyrus, Courier, and Communigate Pro servers all behave in this way. I consider this to be erroneous server behavior since no "adding" took place. A more important thing to remember is that a server may refuse to do an operation (and send a tagged NO) for any reason that it deems fit. There is at least one implemention (UW) that returns NO with an error message to the effect that the name is already subscribed; and it is clearly within the right of such servers to do so. Not surprisingly, I consider the UW server's behavior to be correct. Now, we must study why a client would attempt to subscribe to a name that is already in the list. I can think of only the following reasons: 1) the client wants a duplicate entry in the subscription list. 2) the client does not check the current subscription list. We can dismiss case (1) right away. We don't have an example of a server which has duplicate subscriptions. We have multiple examples of servers which do not. We have some number of servers which refuse to do the subscription, and some other number of servers which no-op the subscription. Case (2) is more interesting. The problem with a client doing this is that it does not have determinate knowledge of the result: a) a server which permits duplicates will send OK, and result in the name being subscribed twice. b) a server which no-ops duplications will send OK, and result in the name being subscribed once. c) a server which prohibits duplicates will send NO, and result in the name being subscribed once. d) a server which doesn't allow that name to be subscribed will send NO, and result in the name not being subscribed. Thus, even if we convince the vendors of Cyrus, Communigate Pro, and Courier to change their servers, that only eliminates case (b); you would still have the (c) vs. (d) ambiguity for a NO response. I don't think that it's worth the effort. The unavoidable conclusion for client authors is: DON'T DO THAT That is; a client should first obtain the subscription list with LSUB, and not attempt to subscribe names that are already subscribed. There's a potential timing race between the LSUB and the SUBSCRIBE command if another session is also subscribing. Fortunately, most SUBSCRIBE commands are at the behest of a human user, and thus dualing SUBSCRIBEs are not an issue in real life. If your client cares, then it should do an LSUB afterwards to see the results.