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.

Reply via email to