Issue #9895 - ensure callback is failed after error in PerMessageDeflateExtension

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2023-06-13 13:02:28 +10:00
parent a471c08717
commit 81447c3e2c
2 changed files with 26 additions and 2 deletions

View File

@ -464,16 +464,18 @@ public class PerMessageDeflateExtension extends AbstractExtension implements Dem
chunk.setPayload(payload);
chunk.setFin(frame.isFin() && complete);
boolean succeedCallback = complete;
boolean completeCallback = complete;
AtomicReference<ByteBuffer> payloadRef = _payloadRef;
Callback payloadCallback = Callback.from(() ->
{
getBufferPool().release(payloadRef.getAndSet(null));
if (succeedCallback)
if (completeCallback)
callback.succeeded();
}, t ->
{
getBufferPool().release(payloadRef.getAndSet(null));
if (completeCallback)
callback.failed(t);
failFlusher(t);
});

View File

@ -33,6 +33,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -92,6 +93,27 @@ public class LargeDeflateTest
assertThat(message, is(sentMessage));
}
@Test
void testDeflateLargerThanMaxMessage() throws Exception
{
ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest();
upgradeRequest.addExtensions("permessage-deflate");
EventSocket clientSocket = new EventSocket();
ByteBuffer message = largePayloads();
Session session = _client.connect(clientSocket, URI.create("ws://localhost:" + _connector.getLocalPort() + "/ws"), upgradeRequest).get();
// Set the maxBinaryMessageSize on the server to be lower than the size of the message.
assertTrue(_serverSocket.openLatch.await(5, TimeUnit.SECONDS));
_serverSocket.session.setMaxBinaryMessageSize(message.remaining() - 1024);
session.getRemote().sendBytes(message);
assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS));
assertTrue(_serverSocket.closeLatch.await(5, TimeUnit.SECONDS));
assertThat(_serverSocket.closeCode, is(StatusCode.MESSAGE_TOO_LARGE));
assertThat(_serverSocket.closeReason, containsString("Binary message too large"));
}
private static ByteBuffer largePayloads()
{
var bytes = new byte[4 * 1024 * 1024];