Bug 57974

Summary: getOpenSessions() bug
Product: Tomcat 8 Reporter: dstojkov <dstojkov2002>
Component: WebSocketAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: minor    
Priority: P2    
Version: 8.0.22   
Target Milestone: ----   
Hardware: All   
OS: All   

Description dstojkov 2015-05-29 11:26:59 UTC
the method getOpenSessions() in the class Session return sessions that are not bound with the endpoint.

In my case I have 2 Endpoints one working with a login/password(go through request.login ) the other not.
When requesting the open sessions for the "logged" one i get even the session of the others.
The specification said that getOpenSessions() return the opened sessions of only one endpoint
Comment 1 dstojkov 2015-06-11 13:31:41 UTC
Actually the endpoint share all the sessions with others Endpoints no matter if it is through login/password or not. 

I dont know how you implemented it but this should be something like:

...
private Map<Endpoint, List<Sessions>>  endPointMappers
...
Set<Sessions> getSessions(Endpoint ep) {
    synchronized(lock) {
        return new TreeSet<>(endPointMappers.get(ep));
    }
}


Any fix in view ? Or at least a comment on this ? This make the use of websockets a true nightmare
Comment 2 Remy Maucherat 2015-06-12 14:37:33 UTC
Did you look at the code ? The endpointSessionMap map is keyed on the class (rather than the endpoint instance) so what you describe can only occur when you have multiple endpoints from the same endpoint class. This is probably not correct (need to check first though ...), and is easy to fix, but running into this issue should not be very common, and it also has an easy workaround. Adjusting severity accordingly.
Comment 3 Remy Maucherat 2015-06-12 16:45:15 UTC
Attempting fix in trunk, will backport if there are no issues.
Comment 4 Mark Thomas 2015-06-12 17:23:31 UTC
This issue will occur frequently in POJO endpoints since they all share the same Endpoint implementation class (which is how I suspect the OP hit this issue).
Comment 5 Remy Maucherat 2015-06-12 17:43:06 UTC
Good point. So I'll backport the fix then.
Comment 6 Remy Maucherat 2015-06-12 19:05:43 UTC
TestWsWebSocketContainer, so it needs more work/review.
Comment 7 Remy Maucherat 2015-06-15 12:35:04 UTC
r1685562 included in 8.0.24
r1685570 included in 7.0.63
Comment 8 Zhang Zhongyi 2018-12-28 03:43:36 UTC
Now getOpenSessions can only return the current session.
The problem is that Endpoint is used as the key of the HashMap but its hashCode and equals method are not overridden. They are directly inherited from Object. 

Each time a new connection comes in a new Endpoint instance is created. Because it uses the hashCode and equals from Object, it will never match any instances created before even if the request is to the same URL.

My suggestion is to use the URI from session.getRequestURI() as the key of the map instead of the Endpoint.
Comment 9 Mark Thomas 2019-01-24 23:12:59 UTC
Thanks for the report.

Fixed in:
- trunk for 9.0.15 onwards
- 8.5.x for 8.5.38 onwards
- 7.0.x for 7.0.93 onwards

While the path works for the server side, the endpoint instance is still the right choice for the client side. This necessitated a little refactoring as the client and server share a session implementation.