Skip to content

Commit 5a8e3a8

Browse files
baranowbfl4via
authored andcommitted
[UNDERTOW-1869] synchronize session/id checks on session creation
1 parent 40efb45 commit 5a8e3a8

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

core/src/main/java/io/undertow/server/session/InMemorySessionManager.java

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ public Session createSession(final HttpServerExchange serverExchange, final Sess
145145
while (sessions.size() >= maxSize && !evictionQueue.isEmpty()) {
146146

147147
String key = evictionQueue.poll();
148+
if(key == null) {
149+
break;
150+
}
148151
UndertowLogger.REQUEST_LOGGER.debugf("Removing session %s as max size has been hit", key);
149152
SessionImpl toRemove = sessions.get(key);
150153
if (toRemove != null) {
@@ -161,39 +164,49 @@ public Session createSession(final HttpServerExchange serverExchange, final Sess
161164
if (config == null) {
162165
throw UndertowMessages.MESSAGES.couldNotFindSessionCookieConfig();
163166
}
167+
164168
String sessionID = config.findSessionId(serverExchange);
169+
boolean idRequested = false;
165170
if (sessionID == null) {
166-
int count = 0;
167-
while (sessionID == null) {
168-
sessionID = sessionIdGenerator.createSessionId();
169-
if (sessions.containsKey(sessionID)) {
171+
sessionID = sessionIdGenerator.createSessionId();
172+
} else {
173+
idRequested = true;
174+
}
175+
SessionImpl session;
176+
synchronized(this.sessions) {
177+
if(this.sessions.containsKey(sessionID)) {
178+
if(idRequested) {
179+
throw UndertowMessages.MESSAGES.sessionWithIdAlreadyExists(sessionID);
180+
} else {
181+
int count = 0;
170182
sessionID = null;
171-
}
172-
if (count++ == 100) {
173-
//this should never happen
174-
//but we guard against pathalogical session id generators to prevent an infinite loop
175-
throw UndertowMessages.MESSAGES.couldNotGenerateUniqueSessionId();
183+
while (sessionID == null) {
184+
sessionID = sessionIdGenerator.createSessionId();
185+
if (sessions.containsKey(sessionID)) {
186+
sessionID = null;
187+
}
188+
if (count++ == 100) {
189+
//this should 'never' happen
190+
//but we guard against pathalogical session id generators to prevent an infinite loop
191+
throw UndertowMessages.MESSAGES.couldNotGenerateUniqueSessionId();
192+
}
193+
}
176194
}
177195
}
178-
} else {
179-
if (sessions.containsKey(sessionID)) {
180-
throw UndertowMessages.MESSAGES.sessionWithIdAlreadyExists(sessionID);
196+
Object evictionToken;
197+
if (evictionQueue != null) {
198+
evictionToken = evictionQueue.offerLastAndReturnToken(sessionID);
199+
} else {
200+
evictionToken = null;
181201
}
202+
session = new SessionImpl(this, sessionID, config, serverExchange.getIoThread(), serverExchange.getConnection().getWorker(), evictionToken, defaultSessionTimeout);
203+
sessions.put(sessionID, session);
204+
config.setSessionId(serverExchange, session.getId());
205+
serverExchange.putAttachment(NEW_SESSION, session);
182206
}
183-
Object evictionToken;
184-
if (evictionQueue != null) {
185-
evictionToken = evictionQueue.offerLastAndReturnToken(sessionID);
186-
} else {
187-
evictionToken = null;
188-
}
189-
final SessionImpl session = new SessionImpl(this, sessionID, config, serverExchange.getIoThread(), serverExchange.getConnection().getWorker(), evictionToken, defaultSessionTimeout);
190-
191-
UndertowLogger.SESSION_LOGGER.debugf("Created session with id %s for exchange %s", sessionID, serverExchange);
192-
sessions.put(sessionID, session);
193-
config.setSessionId(serverExchange, session.getId());
194207
session.bumpTimeout();
208+
UndertowLogger.SESSION_LOGGER.debugf("Created session with id %s for exchange %s", sessionID, serverExchange);
195209
sessionListeners.sessionCreated(session, serverExchange);
196-
serverExchange.putAttachment(NEW_SESSION, session);
197210

198211
if(statisticsEnabled) {
199212
createdSessionCount.incrementAndGet();
@@ -620,13 +633,16 @@ public SessionManager getSessionManager() {
620633
@Override
621634
public String changeSessionId(final HttpServerExchange exchange, final SessionConfig config) {
622635
final String oldId = sessionId;
623-
String newId = sessionManager.sessionIdGenerator.createSessionId();
624-
this.sessionId = newId;
625-
if(!invalid) {
626-
sessionManager.sessions.put(newId, this);
627-
config.setSessionId(exchange, this.getId());
636+
String newId = null;
637+
synchronized(sessionManager.sessions) {
638+
newId = sessionManager.sessionIdGenerator.createSessionId();
639+
this.sessionId = newId;
640+
if(!invalid) {
641+
sessionManager.sessions.put(newId, this);
642+
config.setSessionId(exchange, this.getId());
643+
}
644+
sessionManager.sessions.remove(oldId);
628645
}
629-
sessionManager.sessions.remove(oldId);
630646
sessionManager.sessionListeners.sessionIdChanged(this, oldId);
631647
UndertowLogger.SESSION_LOGGER.debugf("Changing session id %s to %s", oldId, newId);
632648

0 commit comments

Comments
 (0)