use of org.apache.hc.core5.http.MalformedChunkCodingException in project httpcomponents-core by apache.
the class Http1IntegrationTest method testTruncatedChunk.
@Test
public void testTruncatedChunk() throws Exception {
final InetSocketAddress serverEndpoint = server.start(new InternalServerHttp1EventHandlerFactory(HttpProcessors.server(), (request, context) -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
@Override
protected void handle(final Message<HttpRequest, String> request, final AsyncServerRequestHandler.ResponseTrigger responseTrigger, final HttpContext context) throws IOException, HttpException {
responseTrigger.submitResponse(new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")), context);
}
}, Http1Config.DEFAULT, CharCodingConfig.DEFAULT, DefaultConnectionReuseStrategy.INSTANCE, scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null) {
@Override
protected ServerHttp1StreamDuplexer createServerHttp1StreamDuplexer(final ProtocolIOSession ioSession, final HttpProcessor httpProcessor, final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory, final Http1Config http1Config, final CharCodingConfig connectionConfig, final ConnectionReuseStrategy connectionReuseStrategy, final NHttpMessageParser<HttpRequest> incomingMessageParser, final NHttpMessageWriter<HttpResponse> outgoingMessageWriter, final ContentLengthStrategy incomingContentStrategy, final ContentLengthStrategy outgoingContentStrategy, final Http1StreamListener streamListener) {
return new ServerHttp1StreamDuplexer(ioSession, httpProcessor, exchangeHandlerFactory, scheme.id, http1Config, connectionConfig, connectionReuseStrategy, incomingMessageParser, outgoingMessageWriter, incomingContentStrategy, outgoingContentStrategy, streamListener) {
@Override
protected ContentEncoder createContentEncoder(final long len, final WritableByteChannel channel, final SessionOutputBuffer buffer, final BasicHttpTransportMetrics metrics) throws HttpException {
if (len == ContentLengthStrategy.CHUNKED) {
return new BrokenChunkEncoder(channel, buffer, metrics);
} else {
return super.createContentEncoder(len, channel, buffer, metrics);
}
}
};
}
});
client.start();
final Future<ClientSessionEndpoint> connectFuture = client.connect("localhost", serverEndpoint.getPort(), TIMEOUT);
final ClientSessionEndpoint streamEndpoint = connectFuture.get();
final AsyncRequestProducer requestProducer = new BasicRequestProducer(Method.GET, createRequestURI(serverEndpoint, "/hello"));
final StringAsyncEntityConsumer entityConsumer = new StringAsyncEntityConsumer() {
@Override
public void releaseResources() {
// Do not clear internal content buffer
}
};
final BasicResponseConsumer<String> responseConsumer = new BasicResponseConsumer<>(entityConsumer);
final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(requestProducer, responseConsumer, null);
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
final Throwable cause = exception.getCause();
Assertions.assertTrue(cause instanceof MalformedChunkCodingException);
Assertions.assertEquals("garbage", entityConsumer.generateContent());
}
use of org.apache.hc.core5.http.MalformedChunkCodingException in project httpcomponents-core by apache.
the class ChunkedInputStream method getChunkSize.
/**
* Expects the stream to start with a chunksize in hex with optional
* comments after a semicolon. The line must end with a CRLF: "a3; some
* comment\r\n" Positions the stream at the start of the next line.
*/
private long getChunkSize() throws IOException {
final State st = this.state;
switch(st) {
case CHUNK_CRLF:
lineBuffer.clear();
final int bytesRead1 = this.buffer.readLine(lineBuffer, inputStream);
if (bytesRead1 == -1) {
throw new MalformedChunkCodingException("CRLF expected at end of chunk");
}
if (!lineBuffer.isEmpty()) {
throw new MalformedChunkCodingException("Unexpected content at the end of chunk");
}
state = State.CHUNK_LEN;
// $FALL-THROUGH$
case CHUNK_LEN:
lineBuffer.clear();
final int bytesRead2 = this.buffer.readLine(lineBuffer, inputStream);
if (bytesRead2 == -1) {
throw new ConnectionClosedException("Premature end of chunk coded message body: closing chunk expected");
}
int separator = lineBuffer.indexOf(';');
if (separator < 0) {
separator = lineBuffer.length();
}
final String s = this.lineBuffer.substringTrimmed(0, separator);
try {
return Long.parseLong(s, 16);
} catch (final NumberFormatException e) {
throw new MalformedChunkCodingException("Bad chunk header: " + s);
}
default:
throw new IllegalStateException("Inconsistent codec state");
}
}
use of org.apache.hc.core5.http.MalformedChunkCodingException in project httpcomponents-core by apache.
the class ChunkDecoder method readChunkHead.
private void readChunkHead() throws IOException {
if (this.lineBuf == null) {
this.lineBuf = new CharArrayBuffer(32);
} else {
this.lineBuf.clear();
}
if (this.endOfChunk) {
if (this.buffer.readLine(this.lineBuf, this.endOfStream)) {
if (!this.lineBuf.isEmpty()) {
throw new MalformedChunkCodingException("CRLF expected at end of chunk");
}
} else {
if (this.buffer.length() > 2 || this.endOfStream) {
throw new MalformedChunkCodingException("CRLF expected at end of chunk");
}
return;
}
this.endOfChunk = false;
}
final boolean lineComplete = this.buffer.readLine(this.lineBuf, this.endOfStream);
final int maxLineLen = this.http1Config.getMaxLineLength();
if (maxLineLen > 0 && (this.lineBuf.length() > maxLineLen || (!lineComplete && this.buffer.length() > maxLineLen))) {
throw new MessageConstraintException("Maximum line length limit exceeded");
}
if (lineComplete) {
int separator = this.lineBuf.indexOf(';');
if (separator < 0) {
separator = this.lineBuf.length();
}
final String s = this.lineBuf.substringTrimmed(0, separator);
try {
this.chunkSize = Long.parseLong(s, 16);
} catch (final NumberFormatException e) {
throw new MalformedChunkCodingException("Bad chunk header: " + s);
}
this.pos = 0L;
} else if (this.endOfStream) {
throw new ConnectionClosedException("Premature end of chunk coded message body: closing chunk expected");
}
}
use of org.apache.hc.core5.http.MalformedChunkCodingException in project httpcomponents-core by apache.
the class TestChunkDecoder method testMissingClosingChunk.
@Test
public void testMissingClosingChunk() throws Exception {
final String s = "10\r\n1234567890123456\r\n" + "5\r\n12345\r\n5\r\n12345\r\n";
final ReadableByteChannel channel = new ReadableByteChannelMock(new String[] { s }, StandardCharsets.US_ASCII);
final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, 0, StandardCharsets.US_ASCII);
final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics();
final ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
final ByteBuffer dst = ByteBuffer.allocate(1024);
Assertions.assertThrows(ConnectionClosedException.class, () -> {
long bytesRead = 0;
try {
while (dst.hasRemaining() && !decoder.isCompleted()) {
final int i = decoder.read(dst);
if (i > 0) {
bytesRead += i;
}
}
} catch (final MalformedChunkCodingException ex) {
Assertions.assertEquals(26L, bytesRead);
Assertions.assertEquals("12345678901234561234512345", CodecTestUtils.convert(dst));
Assertions.assertTrue(decoder.isCompleted());
throw ex;
}
});
}
Aggregations