From 3b1d207c9dc1379410713ac930c7675e132efb58 Mon Sep 17 00:00:00 2001 From: Maxim Nesen Date: Wed, 23 Sep 2020 06:41:02 +0200 Subject: [PATCH] HTTP 100-Continue handling arranged Signed-off-by: Maxim Nesen --- .../jersey/client/ClientProperties.java | 10 +++--- .../client/http/Expect100ContinueFeature.java | 22 ++++++++++++- .../client/internal/HttpUrlConnector.java | 18 +++++----- .../Expect100ContinueTest.java | 33 ++++++++++--------- 4 files changed, 53 insertions(+), 30 deletions(-) diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java index dab9c8cc5a..b01857adcc 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java @@ -406,8 +406,8 @@ public final class ClientProperties { public static final String REQUEST_ENTITY_PROCESSING = "jersey.config.client.request.entity.processing"; /** - * Registers 100-Continue value for Expect header processing to be set in HttpUrlConnector (default Jersey - * connector) + * Allows for HTTP Expect:100-Continue being handled by the HttpUrlConnector (default Jersey + * connector). * * @since 2.32 */ @@ -415,7 +415,7 @@ public final class ClientProperties { /** * Property for threshold size for content length after which Expect:100-Continue header would be applied - * before the main request + * before the main request. * * @since 2.32 */ @@ -424,11 +424,11 @@ public final class ClientProperties { /** * Default threshold size (64kb) after which which Expect:100-Continue header would be applied before - * the main request + * the main request. * * @since 2.32 */ - public static final Long DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE = 64000L; + public static final Long DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE = 65536L; private ClientProperties() { // prevents instantiation diff --git a/core-client/src/main/java/org/glassfish/jersey/client/http/Expect100ContinueFeature.java b/core-client/src/main/java/org/glassfish/jersey/client/http/Expect100ContinueFeature.java index ecdd2220b2..3af806c994 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/http/Expect100ContinueFeature.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/http/Expect100ContinueFeature.java @@ -28,10 +28,30 @@ public class Expect100ContinueFeature implements Feature { public Expect100ContinueFeature() { this(ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE); } - public Expect100ContinueFeature(long thresholdSize) { + + private Expect100ContinueFeature(long thresholdSize) { this.thresholdSize = thresholdSize; } + /** + * Creates Expect100ContinueFeature with custom (not default) threshold size for content length. + * + * @param thresholdSize size of threshold + * @return Expect100Continue Feature + */ + public static Expect100ContinueFeature withCustomThreshold(long thresholdSize) { + return new Expect100ContinueFeature(thresholdSize); + } + + /** + * Creates Expect100Continue Feature with default threshold size + * + * @return Expect100Continue Feature + */ + public static Expect100ContinueFeature basic() { + return new Expect100ContinueFeature(); + } + @Override public boolean configure(FeatureContext configurableContext) { if (configurableContext.getConfiguration().getProperty( diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java index 692f352a43..cd017053fb 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java @@ -333,14 +333,8 @@ private ClientResponse _apply(final ClientRequest request) throws IOException { if (entity != null) { RequestEntityProcessing entityProcessing = request.resolveProperty( ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class); - final Long expectContinueSizeThreshold = ClientProperties.getValue( - request.getConfiguration().getProperties(), - ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, - ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE, Long.class); final long length = request.getLengthLong(); - final boolean allowStreaming = length > expectContinueSizeThreshold - || entityProcessing == RequestEntityProcessing.CHUNKED; if (entityProcessing == null || entityProcessing != RequestEntityProcessing.BUFFERED) { if (fixLengthStreaming && length > 0) { @@ -358,7 +352,7 @@ private ClientResponse _apply(final ClientRequest request) throws IOException { } } - processExpect100Continue(request, uc, allowStreaming); + processExpect100Continue(request, uc, length, entityProcessing); request.setStreamProvider(contentLength -> { setOutboundHeaders(request.getStringHeaders(), uc); @@ -536,10 +530,18 @@ public Object run() throws NoSuchFieldException, } } - private void processExpect100Continue(ClientRequest request, HttpURLConnection uc, boolean allowStreaming) { + private void processExpect100Continue(ClientRequest request, HttpURLConnection uc, + long length, RequestEntityProcessing entityProcessing) { final Boolean expectContinueActivated = ClientProperties.getValue(request.getConfiguration().getProperties(), ClientProperties.EXPECT_100_CONTINUE, Boolean.class); + final Long expectContinueSizeThreshold = ClientProperties.getValue( + request.getConfiguration().getProperties(), + ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, + ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE, Long.class); + + final boolean allowStreaming = length > expectContinueSizeThreshold + || entityProcessing == RequestEntityProcessing.CHUNKED; if (!Boolean.TRUE.equals(expectContinueActivated) || !("POST".equals(uc.getRequestMethod()) || "PUT".equals(uc.getRequestMethod())) diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java index f298deddeb..82b7e7abf6 100644 --- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java +++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java @@ -38,6 +38,9 @@ public class Expect100ContinueTest extends JerseyTest { private static final String RESOURCE_PATH = "expect"; + private static final String ENTITY_STRING = "1234567890123456789012345678901234567890123456789012" + + "3456789012345678901234567890"; + @Path(RESOURCE_PATH) public static class Expect100ContinueResource { @@ -73,52 +76,50 @@ protected void configureClient(ClientConfig config) { @Test public void testExpect100Continue() { - final Response response = target(RESOURCE_PATH).request().post(Entity.text("123456789012345678901234" - + "56789012345678901234567890123456789012345678901234567890")); + final Response response = target(RESOURCE_PATH).request().post(Entity.text(ENTITY_STRING)); assertEquals("Expected 200", 200, response.getStatus()); //no Expect header sent - responce OK } @Test public void testExpect100ContinueChunked() { - final Response response = target(RESOURCE_PATH).register(new Expect100ContinueFeature()) + final Response response = target(RESOURCE_PATH).register(Expect100ContinueFeature.basic()) .property(ClientProperties.REQUEST_ENTITY_PROCESSING, - RequestEntityProcessing.CHUNKED).request().post(Entity.text("123456789012345678901234" - + "56789012345678901234567890123456789012345678901234567890")); + RequestEntityProcessing.CHUNKED).request().post(Entity.text(ENTITY_STRING)); assertEquals("Expected 204", 204, response.getStatus()); //Expect header sent - No Content response } @Test public void testExpect100ContinueBuffered() { - final Response response = target(RESOURCE_PATH).register(new Expect100ContinueFeature()) + final Response response = target(RESOURCE_PATH).register(Expect100ContinueFeature.basic()) .property(ClientProperties.REQUEST_ENTITY_PROCESSING, - RequestEntityProcessing.BUFFERED).request().header(HttpHeaders.CONTENT_LENGTH, 65000L) - .post(Entity.text("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); + RequestEntityProcessing.BUFFERED).request().header(HttpHeaders.CONTENT_LENGTH, 67000L) + .post(Entity.text(ENTITY_STRING)); assertEquals("Expected 204", 204, response.getStatus()); //Expect header sent - No Content response } @Test public void testExpect100ContinueCustomLength() { - final Response response = target(RESOURCE_PATH).register(new Expect100ContinueFeature(100L)) + final Response response = target(RESOURCE_PATH).register(Expect100ContinueFeature.withCustomThreshold(100L)) .request().header(HttpHeaders.CONTENT_LENGTH, 101L) - .post(Entity.text("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); + .post(Entity.text(ENTITY_STRING)); assertEquals("Expected 204", 204, response.getStatus()); //Expect header sent - No Content response } @Test public void testExpect100ContinueCustomLengthWrong() { - final Response response = target(RESOURCE_PATH).register(new Expect100ContinueFeature(100L)) + final Response response = target(RESOURCE_PATH).register(Expect100ContinueFeature.withCustomThreshold(100L)) .request().header(HttpHeaders.CONTENT_LENGTH, 99L) - .post(Entity.text("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); - assertEquals("Expected 200", 200, response.getStatus()); //Expect header sent - No Content response + .post(Entity.text(ENTITY_STRING)); + assertEquals("Expected 200", 200, response.getStatus()); //Expect header NOT sent - low request size } @Test public void testExpect100ContinueCustomLengthProperty() { final Response response = target(RESOURCE_PATH) .property(ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 555L) - .register(new Expect100ContinueFeature()) + .register(Expect100ContinueFeature.basic()) .request().header(HttpHeaders.CONTENT_LENGTH, 666L) - .post(Entity.text("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); + .post(Entity.text(ENTITY_STRING)); assertEquals("Expected 204", 204, response.getStatus()); //Expect header sent - No Content response } @@ -128,7 +129,7 @@ public void testExpect100ContinueRegisterViaCustomProperty() { .property(ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 43L) .property(ClientProperties.EXPECT_100_CONTINUE, Boolean.TRUE) .request().header(HttpHeaders.CONTENT_LENGTH, 44L) - .post(Entity.text("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); + .post(Entity.text(ENTITY_STRING)); assertEquals("Expected 204", 204, response.getStatus()); //Expect header sent - No Content response } }