First off, this is the 2nd [potential] bug I've reposted from the user list, so
my apologies. After reading the mailing list descriptions, it seems potential
bugs should be posted to the DEV list. If this is wrong, just let me know.
Potential Bug?
============
I [think] there may be a problem in Tomcat's static UpgradeUtil.doUpgrade logic
when handling concurrent connection/upgrade requests that rely on a custom
ServerEndpointConfig.Configurator.modifyHandshake to grab [per-upgrade-request]
client header values and inject them into the wsSession that is being created.
Specifically, the static doUpgrade does not appear to make a copy of the
ServerEndpointConfig before calling modifyHandshake. As a result, any
per-connection headers the Configurator may grab and put in the
ServerEndpointConfig.UserProperties map will be overwritten by the last upgrade
request that occurs before the upgrade logic creates the new wsSession in the
WsHttpUpgradeHandler.init call.
I am able to replicate this very easily by using the following server
configurator code. By making concurrent websocket connect requests that place
a unique "client-id" in the upgrade request headers, then grabbing that
"client-id" property using the code below, ALL websocket sessions that get
created will have the last "client-id" header value that came in concurrently.
public class Jsr356ServerConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest
request, HandshakeResponse response)
{
// get the request headers - looking for security claims and
endpoint ID
// claims will be checked in the OnOpen call and the connection
closed if AUTH check fails
Map<String, List<String>> headers = request.getHeaders();
String id = headers.get("client-id").get(0);
config.getUserProperties().put("client-id", id);
}
}
@ServerEndpoint(...)
Public class MyServer
{
@OnOpen
public void onOpen(Session session)
{
String id = (String) session.getUserProperties().get("client-id");
_logger.warn("client ID: {}", id);
}
}
Based on chapter 3 of the JSR-356 API document, the actual websocket handshake
process defined in the websocket spec, and the online description of the
process in this stackoverflow link
(http://stackoverflow.com/questions/17936440/accessing-httpsession-from-httpservletrequest-in-a-web-socket-socketendpoint/17994303#17994303),
it appears that we should be able to pass per-client information in the
upgrade headers and we should be able to get them into the endpoint INSTANCE's
Session user properties.
If this is a bug, please confirm and I will create a bugzilla entry, as it is
very important that that we be able to do what I've described above.
If this is not a bug, can someone please describe how to obtain per-client
instance data during the websocket handshake/onOpen process?
Thanks,
Bob