Fix ProtobufDecoder handling of split message size

This commit introduces a new readMessageSize(DataBuffer input) private
method, inspired from CodedInputStream#readRawVarint32(int, InputStream)
and adapted for DataBuffer using MessageDecoderFunction fields in
order to support use cases where the message size is split between
distinct chunks.

It also fixes handling of end of streams by using
DataBuffer#readableByteCount instead of -1 which is only relevant with
InputStream.

Issue: SPR-17429
This commit is contained in:
Sebastien Deleuze
2018-11-23 13:44:38 +01:00
parent 77ab88b144
commit 91de8d265e
2 changed files with 96 additions and 5 deletions

View File

@@ -128,7 +128,9 @@ public class ProtobufDecoderTests extends AbstractDecoderTestCase<ProtobufDecode
}
@Test
public void decodeSplitChunks() throws IOException {
public void decodeSplitChunks() {
Flux<DataBuffer> input = Flux.just(this.testMsg1, this.testMsg2)
.flatMap(msg -> Mono.defer(() -> {
DataBuffer buffer = this.bufferFactory.allocateBuffer();
@@ -158,6 +160,44 @@ public class ProtobufDecoderTests extends AbstractDecoderTestCase<ProtobufDecode
.verifyComplete());
}
@Test // SPR-17429
public void decodeSplitMessageSize() {
this.decoder.setMaxMessageSize(100009);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10000; i++) {
builder.append("azertyuiop");
}
Msg bigMessage = Msg.newBuilder().setFoo(builder.toString()).setBlah(secondMsg2).build();
Flux<DataBuffer> input = Flux.just(bigMessage, bigMessage)
.flatMap(msg -> Mono.defer(() -> {
DataBuffer buffer = this.bufferFactory.allocateBuffer();
try {
msg.writeDelimitedTo(buffer.asOutputStream());
return Mono.just(buffer);
}
catch (IOException e) {
release(buffer);
return Mono.error(e);
}
}))
.flatMap(buffer -> {
int len = 2;
Flux<DataBuffer> result = Flux.just(
DataBufferUtils.retain(buffer.slice(0, len)),
DataBufferUtils
.retain(buffer.slice(len, buffer.readableByteCount() - len))
);
release(buffer);
return result;
});
testDecode(input, Msg.class, step -> step
.expectNext(bigMessage)
.expectNext(bigMessage)
.verifyComplete());
}
@Test
public void decodeMergedChunks() throws IOException {
DataBuffer buffer = this.bufferFactory.allocateBuffer();