Java Bayeux Client can send a disconnect message without a clientId
See original GitHub issueI’ve noticed that it’s possible for the Java Bayeux Client to send a /meta/disconnect
message without a clientId
.
According to the protocol documentation, a /meta/disconnect
message must include a clientId
.
Steps to Reproduce
- Ask the client to handshake and then immediately attempt to disconnect.
client.handshake();
client.disconnect();
Expected Result
-
I’d expect the
handshake()
call to make the client enter into thehandshaking
session state and send ameta/handshake
message. -
I’d expect the following immediate
disconnect()
call to make the client enter into either thedisconnecting
orterminating
state and not send a/meta/disconnect
message since the client doesn’t yet have aclientId
to include in the message.
Actual Result
-
The
handshake()
call makes the client enter into thehandshaking
session state and send ameta/handshake
message. -
The following immediate
disconnect()
call makes the client enter into thedisconnecting
state and send a/meta/disconnect
message without aclientId
.
Additional Information
Looking at the code, it’s currently legal for the client to transition directly from handshaking
to disconnecting
state:
private boolean isUpdateableTo(State newState) {
switch (this) {
case DISCONNECTED:
return newState == HANDSHAKING;
case HANDSHAKING:
case REHANDSHAKING:
return EnumSet.of(REHANDSHAKING, HANDSHAKEN, DISCONNECTING, TERMINATING).contains(newState);
case HANDSHAKEN:
return EnumSet.of(CONNECTING, DISCONNECTING, TERMINATING).contains(newState);
case CONNECTING:
case CONNECTED:
case UNCONNECTED:
return EnumSet.of(REHANDSHAKING, CONNECTED, UNCONNECTED, DISCONNECTING, TERMINATING).contains(newState);
case DISCONNECTING:
return newState == TERMINATING;
case TERMINATING:
return newState == DISCONNECTED;
default:
throw new IllegalStateException();
}
}
I wonder if transitioning from handshaking
or rehandshaking
directly to disconnecting
should be an illegal transition. Instead, maybe the client should transition directly to terminating
since the client can’t have a clientId
when handshaking
and may not have a clientId
when rehandshaking
. (Side note – would it make sense to always clear the clientId
before rehandshaking
anyway)?
Alternatively, maybe the disconnecting
state could skip sending the /meta/disconnect
message if the client is coming from handshaking
or rehandshaking
states. This would likely require updating the documentation for the disconnecting
state since it currently implies that a disconnect message will be sent in this state.
/**
* State assumed when the disconnect is being sent
*/
DISCONNECTING,
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (2 by maintainers)
CometD API were designed a while ago, and today’s design may be different and more up-to-date with current technologies and patterns.
So if you’re designing new APIs, maybe you want to make sure that
handshake()
returns something on which you can calldisconnect()
, so that there is less ambiguity on how to use the API.Regarding the case at hand, I don’t think the server should disconnect all sessions for a particular
BAYEUX_BROWSER
if it gets a disconnect withoutclientId
. The current behavior is harmless, in a way: the client will be disconnected, and the server will time out that session - not immediately but eventually that session will be gone.We may indeed avoid to send the disconnect message, though - it will have the same effect (client disconnected and server timing out the session).
Makes sense. Thanks again for the help!