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) {
|
public Response toResponse(IOException e) {
|
||||||
if (!(e.getCause() instanceof java.util.concurrent.TimeoutException)) {
|
if (!(e.getCause() instanceof java.util.concurrent.TimeoutException)) {
|
||||||
logger.warn("IOExceptionMapper", e);
|
logger.warn("IOExceptionMapper", e);
|
||||||
} else if (e.getCause().getMessage().startsWith("Idle timeout expired")) {
|
} else {
|
||||||
return Response.status(Response.Status.REQUEST_TIMEOUT).build();
|
// 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();
|
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