Issue #6728 - QUIC and HTTP/3

- Fixed HttpChannelOverHTTP3 input reading.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2021-11-02 16:51:03 +01:00
parent fd118a4766
commit 6aedfe52f1
3 changed files with 49 additions and 47 deletions

View File

@ -297,16 +297,12 @@ public class HttpChannelOverHTTP3 extends HttpChannel
}
}
Stream.Data data = stream.readData();
if (data != null)
{
HttpInput.Content result = newContent(data);
try (AutoLock l = lock.lock())
HttpInput.Content result = readContent();
if (result != null)
{
if (LOG.isDebugEnabled())
LOG.debug("need content read content {} on {}", result, this);
content = result;
}
LOG.debug("need content read content {} on {}", this.content, this);
return true;
}
@ -321,41 +317,16 @@ public class HttpChannelOverHTTP3 extends HttpChannel
{
HttpInput.Content result;
try (AutoLock l = lock.lock())
{
if (content != null)
{
result = content;
if (!result.isSpecial())
content = null;
if (LOG.isDebugEnabled())
LOG.debug("produced content {} on {}", result, this);
return result;
}
}
Stream.Data data = stream.readData();
if (LOG.isDebugEnabled())
LOG.debug("read {} on {}", data, this);
if (data == null)
if (result == null)
result = readContent();
if (result == null)
return null;
result = newContent(data);
try (AutoLock l = lock.lock())
{
content = result;
}
boolean handle = onContent(result);
boolean isLast = data.isLast();
if (isLast)
{
boolean handleContent = onContentComplete();
// This will generate EOF -> must happen before onContentProducible().
boolean handleRequest = onRequestComplete();
handle |= handleContent | handleRequest;
}
if (!result.isSpecial())
{
HttpInput.Content newContent = result.isEof() ? new HttpInput.EofContent() : null;
@ -365,10 +336,41 @@ public class HttpChannelOverHTTP3 extends HttpChannel
}
}
if (LOG.isDebugEnabled())
LOG.debug("produced new content {} on {}", result, this);
LOG.debug("produced content {} on {}", result, this);
return result;
}
private HttpInput.Content readContent()
{
Stream.Data data = stream.readData();
if (LOG.isDebugEnabled())
LOG.debug("read data {} on {}", data, this);
if (data != null)
{
HttpInput.Content result = newContent(data);
boolean handle = onContent(result);
try (AutoLock l = lock.lock())
{
if (LOG.isDebugEnabled())
LOG.debug("read content {} on {}", result, this);
content = result;
}
if (data.isLast())
{
boolean handleContent = onContentComplete();
// This will generate EOF -> must happen before onContentProducible().
boolean handleRequest = onRequestComplete();
handle |= handleContent | handleRequest;
}
return result;
}
return null;
}
private HttpInput.Content newContent(Stream.Data data)
{
return new DataContent(data);

View File

@ -596,7 +596,7 @@ public class QuicheConnection
if (written == LibQuiche.quiche_error.QUICHE_ERR_DONE)
return;
if (written < 0L)
throw new IOException(" failed to write FIN to stream " + streamId + "; err=" + LibQuiche.quiche_error.errToString(written));
throw new IOException("failed to write FIN to stream " + streamId + "; err=" + LibQuiche.quiche_error.errToString(written));
}
}

View File

@ -92,14 +92,14 @@ public class HttpClientLoadTest extends AbstractTest<HttpClientLoadTest.LoadTran
int iterations = 500;
for (int i = 0; i < runs; ++i)
{
run(iterations);
run(transport, iterations);
}
// Re-run after warmup
iterations = 5_000;
iterations = 1_000;
for (int i = 0; i < runs; ++i)
{
run(iterations);
run(transport, iterations);
}
System.gc();
@ -143,10 +143,10 @@ public class HttpClientLoadTest extends AbstractTest<HttpClientLoadTest.LoadTran
int iterations = 256;
IntStream.range(0, 16).parallel().forEach(i ->
IntStream.range(0, runs).forEach(j ->
run(iterations)));
run(transport, iterations)));
}
private void run(int iterations)
private void run(Transport transport, int iterations)
{
CountDownLatch latch = new CountDownLatch(iterations);
List<String> failures = new ArrayList<>();
@ -173,7 +173,7 @@ public class HttpClientLoadTest extends AbstractTest<HttpClientLoadTest.LoadTran
long end = System.nanoTime();
task.cancel();
long elapsed = TimeUnit.NANOSECONDS.toMillis(end - begin);
logger.info("{} requests in {} ms, {} req/s", iterations, elapsed, elapsed > 0 ? iterations * 1000L / elapsed : -1);
logger.info("{} {} requests in {} ms, {} req/s", iterations, transport, elapsed, elapsed > 0 ? iterations * 1000L / elapsed : -1);
for (String failure : failures)
{