Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x

This commit is contained in:
gregw 2020-11-30 17:33:21 +01:00
commit 20f6dc1ace
3 changed files with 100 additions and 41 deletions

View File

@ -29,7 +29,7 @@ jetty-9.4.35.v20201120 - 20 November 2020
+ 5539 StatisticsServlet output is not valid
+ 5562 ArrayTernaryTrie consumes too much memory
+ 5575 Add SEARCH as a known HttpMethod
+ 5605 java.io.IOException: unconsumed input during http request parsing
+ 5605 CVE-2020-27218 java.io.IOException: unconsumed input during http request parsing
+ 5633 Allow to configure HttpClient request authority
jetty-9.4.34.v20201102 - 02 November 2020

View File

@ -1,40 +0,0 @@
This is the jetty websocket module that provides a websocket server and the skeleton of a websocket client.
By default websockets is included with a jetty release (with these classes either being in the jetty-websocket jar or in
an aggregate jar (see below).
In order to accept a websocket connection, the websocket handshake request is first routed to normal HTTP request
handling, which must respond with a 101 response and an instance of WebSocketConnection set as the
"org.eclipse.jetty.io.Connection" request attribute. The accepting behaviour is provided by WebSocketHandler or the
WebSocketServlet class, both of which delegate to the WebSocketFactory class.
A TestServer and TestClient class are available, and can be run either directly from an IDE (if jetty source is
imported), or from the command line with
java -cp jetty-aggregate/jetty-all/target/jetty-all-7.x.y.jar:jetty-distribution/target/distribution/lib/servlet-api-2.5.jar
org.eclipse.jetty.websocket.TestServer --help
java -cp jetty-aggregate/jetty-all/target/jetty-all-7.x.y.jar:jetty-distribution/target/distribution/lib/servlet-api-2.5.jar
org.eclipse.jetty.websocket.TestClient --help
Without a protocol specified, the client will just send/receive websocket PING/PONG packets. A protocol can be specified for testing other
aspects of websocket. Specifically the server and client understand the following protocols:
org.ietf.websocket.test-echo
Websocket messages are sent by the client and the server will echo every frame.
org.ietf.websocket.test-echo-broadcast
Websocket messages are sent by the client and the server will echo every frame to every connection.
org.ietf.websocket.test-echo-assemble
Websocket messages are sent by the client and the server will echo assembled messages as a single frame.
org.ietf.websocket.test-echo-fragment
Websocket messages are sent and the server will echo each message fragmented into 2 frames.

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.http.client;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.rmi.ServerException;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
@ -53,6 +54,7 @@ import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
@ -472,6 +474,103 @@ public class ServerTimeoutsTest extends AbstractTest<TransportScenario>
}
}
@ParameterizedTest
@ArgumentsSource(TransportProvider.class)
@Disabled // TODO #5737
public void testBlockingReadInOtherThreadThenComplete(Transport transport) throws Exception
{
init(transport);
BlockingReadAndCompleteHandler handler = new BlockingReadAndCompleteHandler();
scenario.start(handler);
try /*(StacklessLogging ignore = new StacklessLogging(HttpChannel.class))*/
{
DeferredContentProvider contentProvider = new DeferredContentProvider(ByteBuffer.allocate(1));
CountDownLatch resultLatch = new CountDownLatch(1);
scenario.client.POST(scenario.newURI())
.content(contentProvider)
.send(result ->
{
if (result.getResponse().getStatus() == 299)
resultLatch.countDown();
});
// Blocking read should error.
assertTrue(handler.readErrorLatch.await(5, TimeUnit.SECONDS));
// request should complete without waiting for content.
assertTrue(handler.readErrorLatch.await(1, TimeUnit.SECONDS));
// Complete the request.
contentProvider.close();
assertTrue(resultLatch.await(5, TimeUnit.SECONDS));
}
catch (Exception e)
{
throw e;
}
}
private static class BlockingReadAndCompleteHandler extends AbstractHandler
{
CountDownLatch readErrorLatch;
CountDownLatch completeLatch;
public BlockingReadAndCompleteHandler()
{
this.readErrorLatch = new CountDownLatch(1);
this.completeLatch = new CountDownLatch(1);
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
baseRequest.setHandled(true);
AsyncContext asyncContext = baseRequest.startAsync();
ServletInputStream input = request.getInputStream();
CountDownLatch reading = new CountDownLatch(1);
new Thread(() ->
{
try
{
response.setStatus(289);
while (input.read() >= 0)
{
reading.countDown();
}
}
catch (IOException x)
{
readErrorLatch.countDown();
}
}).start();
try
{
reading.await();
}
catch (Exception e)
{
throw new ServletException(e);
}
new Thread(() ->
{
try
{
Thread.sleep(500);
response.setStatus(299);
asyncContext.complete();
completeLatch.countDown();
}
catch (InterruptedException x)
{
throw new IllegalStateException(x);
}
}).start();
}
}
@ParameterizedTest
@ArgumentsSource(TransportProvider.class)
public void testAsyncReadHttpIdleTimeoutOverridesIdleTimeout(Transport transport) throws Exception