Jetty 10: Improvements to HttpConnection when reading 0 bytes. (#12156)
* Improvements to HttpConnection when reading 0 bytes. --------- Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
2aec6cbbc8
commit
8259eabbc7
|
@ -375,20 +375,31 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
|
|||
filled = getEndPoint().fill(requestBuffer);
|
||||
|
||||
if (filled > 0)
|
||||
{
|
||||
bytesIn.add(filled);
|
||||
else if (filled < 0)
|
||||
_parser.atEOF();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filled < 0)
|
||||
_parser.atEOF();
|
||||
releaseRequestBuffer();
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} filled {} {}", this, filled, _retainableByteBuffer);
|
||||
|
||||
return filled;
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to fill from endpoint {}", getEndPoint(), e);
|
||||
LOG.debug("Unable to fill from endpoint {}", getEndPoint(), x);
|
||||
_parser.atEOF();
|
||||
if (_retainableByteBuffer != null)
|
||||
{
|
||||
_retainableByteBuffer.clear();
|
||||
releaseRequestBuffer();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,14 +45,21 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.RetainableByteBufferPool;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.eclipse.jetty.http.client.Transport.FCGI;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
@ -63,6 +70,22 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|||
|
||||
public class HttpClientContinueTest extends AbstractTest<TransportScenario>
|
||||
{
|
||||
@AfterEach
|
||||
public void dispose()
|
||||
{
|
||||
if (scenario == null || scenario.connector == null)
|
||||
return;
|
||||
ByteBufferPool bbp = scenario.connector.getByteBufferPool();
|
||||
if (bbp == null)
|
||||
return;
|
||||
RetainableByteBufferPool rbbp = bbp.asRetainableByteBufferPool();
|
||||
if (rbbp instanceof ArrayRetainableByteBufferPool.Tracking)
|
||||
{
|
||||
ArrayRetainableByteBufferPool.Tracking tracking = (ArrayRetainableByteBufferPool.Tracking)rbbp;
|
||||
await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> assertThat("Server leaks: " + tracking.dumpLeaks(), tracking.getLeaks().size(), is(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Transport transport) throws IOException
|
||||
{
|
||||
|
@ -852,6 +875,28 @@ public class HttpClientContinueTest extends AbstractTest<TransportScenario>
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(TransportProvider.class)
|
||||
public void testExpect100ContinueThen404(Transport transport) throws Exception
|
||||
{
|
||||
init(transport);
|
||||
|
||||
// No Handler so every request is a 404.
|
||||
scenario.start((Handler)null);
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AsyncRequestContent requestContent = new AsyncRequestContent("text-plain");
|
||||
scenario.client.newRequest(scenario.newURI())
|
||||
.headers(headers -> headers.put(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE))
|
||||
.body(requestContent)
|
||||
.send(result -> latch.countDown());
|
||||
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
private void readRequestHeaders(InputStream input) throws IOException
|
||||
{
|
||||
int crlfs = 0;
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.eclipse.jetty.http3.client.http.HttpClientTransportOverHTTP3;
|
|||
import org.eclipse.jetty.http3.server.AbstractHTTP3ServerConnectionFactory;
|
||||
import org.eclipse.jetty.http3.server.HTTP3ServerConnectionFactory;
|
||||
import org.eclipse.jetty.http3.server.HTTP3ServerConnector;
|
||||
import org.eclipse.jetty.io.ArrayByteBufferPool;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.jmx.MBeanContainer;
|
||||
import org.eclipse.jetty.quic.server.QuicServerConnector;
|
||||
|
@ -122,7 +124,8 @@ public class TransportScenario
|
|||
case H2C:
|
||||
case H2:
|
||||
case FCGI:
|
||||
return new ServerConnector(server, 1, 1, provideServerConnectionFactory(transport));
|
||||
ByteBufferPool bufferPool = new ArrayByteBufferPool.Tracking();
|
||||
return new ServerConnector(server, null, null, bufferPool, 1, 1, provideServerConnectionFactory(transport));
|
||||
case H3:
|
||||
HTTP3ServerConnector http3ServerConnector = new HTTP3ServerConnector(server, sslContextFactory, provideServerConnectionFactory(transport));
|
||||
http3ServerConnector.getQuicConfiguration().setPemWorkDirectory(Path.of(System.getProperty("java.io.tmpdir")));
|
||||
|
|
Loading…
Reference in New Issue