Skip to content

Commit 12a6f2d

Browse files
committed
Fix #33906: remove corrupt sessions
1 parent b4ba90b commit 12a6f2d

1 file changed

Lines changed: 33 additions & 1 deletion

File tree

src/main/java/eu/openanalytics/containerproxy/RedisSessionConfig.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,15 @@
3131
import org.springframework.context.annotation.Import;
3232
import org.springframework.core.env.Environment;
3333
import org.springframework.data.redis.connection.RedisConnectionFactory;
34+
import org.springframework.data.redis.core.RedisOperations;
35+
import org.springframework.session.MapSession;
3436
import org.springframework.session.config.SessionRepositoryCustomizer;
3537
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
38+
import org.springframework.session.data.redis.RedisSessionMapper;
3639

40+
import java.util.Map;
3741
import java.util.Objects;
42+
import java.util.function.BiFunction;
3843

3944
@Configuration
4045
@ConditionalOnProperty(name = "spring.session.store-type", havingValue = "redis")
@@ -59,7 +64,10 @@ public String getRedisNamespace() {
5964

6065
@Bean
6166
public SessionRepositoryCustomizer<RedisIndexedSessionRepository> sessionRepositorySessionRepositoryCustomizer() {
62-
return redisIndexedSessionRepository -> redisIndexedSessionRepository.setRedisKeyNamespace(redisNamespace);
67+
return redisIndexedSessionRepository -> {
68+
redisIndexedSessionRepository.setRedisKeyNamespace(redisNamespace);
69+
redisIndexedSessionRepository.setRedisSessionMapper(new SafeRedisSessionMapper(redisIndexedSessionRepository.getSessionRedisOperations()));
70+
};
6371
}
6472

6573
@Bean
@@ -84,4 +92,28 @@ public Health health() {
8492
}
8593
}
8694

95+
class SafeRedisSessionMapper implements BiFunction<String, Map<String, Object>, MapSession> {
96+
97+
private final RedisSessionMapper delegate = new RedisSessionMapper();
98+
99+
private final RedisOperations<String, Object> redisOperations;
100+
101+
SafeRedisSessionMapper(RedisOperations<String, Object> redisOperations) {
102+
this.redisOperations = redisOperations;
103+
}
104+
105+
@Override
106+
public MapSession apply(String sessionId, Map<String, Object> map) {
107+
try {
108+
return this.delegate.apply(sessionId, map);
109+
}
110+
catch (IllegalStateException ex) {
111+
// do not invoke RedisIndexedSessionRepository#deleteById to avoid an infinite loop because the method also invokes this mapper
112+
redisOperations.delete(getRedisNamespace() + ":sessions:" + sessionId);
113+
return null;
114+
}
115+
}
116+
117+
}
118+
87119
}

0 commit comments

Comments
 (0)