Include HTTP/2 stream idle timeouts in IOExceptionMapper
This commit is contained in:
parent
3cc740cda3
commit
9f6a6d7f5b
|
@ -21,8 +21,19 @@ public class IOExceptionMapper implements ExceptionMapper<IOException> {
|
|||
public Response toResponse(IOException e) {
|
||||
if (!(e.getCause() instanceof java.util.concurrent.TimeoutException)) {
|
||||
logger.warn("IOExceptionMapper", e);
|
||||
} else if (e.getCause().getMessage().startsWith("Idle timeout expired")) {
|
||||
return Response.status(Response.Status.REQUEST_TIMEOUT).build();
|
||||
} else {
|
||||
// Some TimeoutExceptions are because the connection is idle, but are only distinguishable using the exception
|
||||
// message
|
||||
final String message = e.getCause().getMessage();
|
||||
final boolean idleTimeout =
|
||||
message != null &&
|
||||
// org.eclipse.jetty.io.IdleTimeout
|
||||
(message.startsWith("Idle timeout expired")
|
||||
// org.eclipse.jetty.http2.HTTP2Session
|
||||
|| (message.startsWith("Idle timeout") && message.endsWith("elapsed")));
|
||||
if (idleTimeout) {
|
||||
return Response.status(Response.Status.REQUEST_TIMEOUT).build();
|
||||
}
|
||||
}
|
||||
|
||||
return Response.status(503).build();
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.mappers;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.core.Response;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class IOExceptionMapperTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testExceptionParsing(final IOException exception, final int expectedStatus) {
|
||||
|
||||
try (Response response = new IOExceptionMapper().toResponse(exception)) {
|
||||
assertEquals(expectedStatus, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
static Stream<Arguments> testExceptionParsing() {
|
||||
return Stream.of(
|
||||
Arguments.of(new IOException(), 503),
|
||||
Arguments.of(new IOException(new TimeoutException("A timeout")), 503),
|
||||
Arguments.of(new IOException(new TimeoutException()), 503),
|
||||
Arguments.of(new IOException(new TimeoutException("Idle timeout 30000 ms elapsed")), 408),
|
||||
Arguments.of(new IOException(new TimeoutException("Idle timeout expired")), 408),
|
||||
Arguments.of(new IOException(new RuntimeException(new TimeoutException("Idle timeout expired"))), 503),
|
||||
Arguments.of(new IOException(new TimeoutException("Idle timeout of another kind expired")), 503)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue