You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/05/31 17:51:07 UTC
[httpcomponents-core] 04/06: Improved classic and async entity
factory methods
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch message-support
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit 0e96b7d8940ddbb850cc9fa6c3599afb6f53720b
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue May 28 11:10:28 2019 +0200
Improved classic and async entity factory methods
---
.../examples/Http2FullDuplexClientExample.java | 5 +-
.../core5/testing/nio/Http1AuthenticationTest.java | 12 +-
.../hc/core5/testing/nio/Http1IntegrationTest.java | 30 +--
.../hc/core5/testing/nio/Http2IntegrationTest.java | 12 +-
.../testing/nio/SingleLineResponseHandler.java | 4 +-
.../hc/core5/http/io/entity/EntityTemplate.java | 12 +-
.../hc/core5/http/io/entity/EntityUtils.java | 2 +-
.../hc/core5/http/io/entity/HttpEntities.java | 224 ++++++++++++++++++++
.../hc/core5/http/io/entity/HttpEntityWrapper.java | 8 +-
.../hc/core5/http/nio/BasicResponseProducer.java | 4 +-
.../entity/AsyncEntityProducerWrapper.java} | 74 +++----
.../http/nio/entity/AsyncEntityProducers.java | 235 +++++++++++++++++++++
.../nio/support/AbstractAsyncServerAuthFilter.java | 4 +-
.../support/ImmediateResponseExchangeHandler.java | 5 +-
.../nio/support/TerminalAsyncServerFilter.java | 4 +-
.../IOCallback.java} | 11 +-
.../org/apache/hc/core5/net/URLEncodedUtils.java | 5 -
.../examples/AsyncFullDuplexClientExample.java | 5 +-
.../http/examples/AsyncServerFilterExample.java | 11 +-
.../http/examples/ClassicPostExecutionExample.java | 34 +--
.../ClassicPostWithTrailersExecutionExample.java | 78 -------
.../hc/core5/http/io/entity/TestEntityUtils.java | 2 +-
.../hc/core5/http/message/TestMessageSupport.java | 10 +-
.../http/protocol/TestStandardInterceptors.java | 6 +-
24 files changed, 577 insertions(+), 220 deletions(-)
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/Http2FullDuplexClientExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/Http2FullDuplexClientExample.java
index 5810a44..fcf2ce1 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/Http2FullDuplexClientExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/Http2FullDuplexClientExample.java
@@ -33,7 +33,6 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpConnection;
@@ -47,7 +46,7 @@ import org.apache.hc.core5.http.nio.BasicResponseConsumer;
import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.RequestChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
@@ -126,7 +125,7 @@ public class Http2FullDuplexClientExample {
final URI requestUri = new URI("http://nghttp2.org/httpbin/post");
final BasicRequestProducer requestProducer = new BasicRequestProducer(
- Methods.POST.name(), requestUri, new BasicAsyncEntityProducer("stuff", ContentType.TEXT_PLAIN));
+ Methods.POST.name(), requestUri, AsyncEntityProducers.create("stuff"));
final BasicResponseConsumer<String> responseConsumer = new BasicResponseConsumer<>(
new StringAsyncEntityConsumer());
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
index b9a47f4..61d9dfe 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
@@ -55,7 +55,7 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.BasicRequestProducer;
import org.apache.hc.core5.http.nio.BasicResponseConsumer;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.support.AbstractAsyncServerAuthFilter;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -145,7 +145,7 @@ public class Http1AuthenticationTest {
@Override
protected AsyncEntityProducer generateResponseContent(final HttpResponse unauthorized) {
- return new BasicAsyncEntityProducer("You shall not pass!!!");
+ return AsyncEntityProducers.create("You shall not pass!!!");
}
})
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
@@ -251,7 +251,7 @@ public class Http1AuthenticationTest {
}
final HttpRequest request1 = new BasicHttpRequest(Methods.POST, target, "/stuff");
final Future<Message<HttpResponse, String>> resultFuture1 = requester.execute(
- new BasicRequestProducer(request1, new BasicAsyncEntityProducer(stuff, ContentType.TEXT_PLAIN)),
+ new BasicRequestProducer(request1, AsyncEntityProducers.create(stuff, ContentType.TEXT_PLAIN)),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null);
final Message<HttpResponse, String> message1 = resultFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertThat(message1, CoreMatchers.notNullValue());
@@ -263,7 +263,7 @@ public class Http1AuthenticationTest {
final HttpRequest request2 = new BasicHttpRequest(Methods.POST, target, "/stuff");
request2.setHeader(HttpHeaders.AUTHORIZATION, "let me pass");
final Future<Message<HttpResponse, String>> resultFuture2 = requester.execute(
- new BasicRequestProducer(request2, new BasicAsyncEntityProducer(stuff, ContentType.TEXT_PLAIN)),
+ new BasicRequestProducer(request2, AsyncEntityProducers.create(stuff, ContentType.TEXT_PLAIN)),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null);
final Message<HttpResponse, String> message2 = resultFuture2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertThat(message2, CoreMatchers.notNullValue());
@@ -291,7 +291,7 @@ public class Http1AuthenticationTest {
final HttpRequest request1 = new BasicHttpRequest(Methods.POST, target, "/stuff");
request1.setVersion(HttpVersion.HTTP_1_0);
final Future<Message<HttpResponse, String>> resultFuture1 = requester.execute(
- new BasicRequestProducer(request1, new BasicAsyncEntityProducer(stuff, ContentType.TEXT_PLAIN)),
+ new BasicRequestProducer(request1, AsyncEntityProducers.create(stuff, ContentType.TEXT_PLAIN)),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null);
final Message<HttpResponse, String> message1 = resultFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertThat(message1, CoreMatchers.notNullValue());
@@ -304,7 +304,7 @@ public class Http1AuthenticationTest {
request2.setVersion(HttpVersion.HTTP_1_0);
request2.setHeader(HttpHeaders.AUTHORIZATION, "let me pass");
final Future<Message<HttpResponse, String>> resultFuture2 = requester.execute(
- new BasicRequestProducer(request2, new BasicAsyncEntityProducer(stuff, ContentType.TEXT_PLAIN)),
+ new BasicRequestProducer(request2, AsyncEntityProducers.create(stuff, ContentType.TEXT_PLAIN)),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null);
final Message<HttpResponse, String> message2 = resultFuture2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertThat(message2, CoreMatchers.notNullValue());
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 2020c14..c633ded 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -106,7 +106,7 @@ import org.apache.hc.core5.http.nio.NHttpMessageParser;
import org.apache.hc.core5.http.nio.NHttpMessageWriter;
import org.apache.hc.core5.http.nio.ResponseChannel;
import org.apache.hc.core5.http.nio.SessionOutputBuffer;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
@@ -401,7 +401,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
for (int i = 0; i < 5; i++) {
final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertNotNull(result);
@@ -434,7 +434,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
for (int i = 0; i < 5; i++) {
queue.add(streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
}
while (!queue.isEmpty()) {
@@ -470,7 +470,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
final HttpRequest request = new BasicHttpRequest(Methods.POST, createRequestURI(serverEndpoint, "/hello"));
request.setVersion(HttpVersion.HTTP_1_0);
final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
- new BasicRequestProducer(request, new BasicAsyncEntityProducer("Hi there")),
+ new BasicRequestProducer(request, AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertNotNull(result);
@@ -571,7 +571,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
for (int i = 0; i < 2; i++) {
queue.add(streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
}
while (!queue.isEmpty()) {
@@ -785,7 +785,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
final HttpRequest request4 = new BasicHttpRequest(Methods.POST, createRequestURI(serverEndpoint, "/echo"));
final Future<Message<HttpResponse, String>> future4 = streamEndpoint.execute(
- new BasicRequestProducer(request4, new BasicAsyncEntityProducer("blah")),
+ new BasicRequestProducer(request4, AsyncEntityProducers.create("blah")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Message<HttpResponse, String> result4 = future4.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
Assert.assertNotNull(result4);
@@ -806,7 +806,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
return new AsyncServerExchangeHandler() {
private final Random random = new Random(System.currentTimeMillis());
- private final AsyncEntityProducer entityProducer = new BasicAsyncEntityProducer(
+ private final AsyncEntityProducer entityProducer = AsyncEntityProducers.create(
"All is well");
@Override
@@ -889,7 +889,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
for (int i = 0; i < 5; i++) {
queue.add(streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/"),
- new BasicAsyncEntityProducer("Some important message")),
+ AsyncEntityProducers.create("Some important message")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
}
while (!queue.isEmpty()) {
@@ -1205,17 +1205,17 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello-1"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final HttpRequest request2 = new BasicHttpRequest(Methods.POST, createRequestURI(serverEndpoint, "/hello-2"));
request2.addHeader(HttpHeaders.CONNECTION, "close");
final Future<Message<HttpResponse, String>> future2 = streamEndpoint.execute(
new BasicRequestProducer(request2,
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Future<Message<HttpResponse, String>> future3 = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello-3"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Message<HttpResponse, String> result1 = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
@@ -1242,7 +1242,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
final Future<Message<HttpResponse, String>> future4 = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello-3"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
try {
future4.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
@@ -1272,17 +1272,17 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello-1"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final HttpRequest request2 = new BasicHttpRequest(Methods.POST, createRequestURI(serverEndpoint, "/hello-2"));
request2.addHeader(HttpHeaders.HOST, "blah:blah");
final Future<Message<HttpResponse, String>> future2 = streamEndpoint.execute(
new BasicRequestProducer(request2,
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Future<Message<HttpResponse, String>> future3 = streamEndpoint.execute(
new BasicRequestProducer(Methods.POST, createRequestURI(serverEndpoint, "/hello-3"),
- new BasicAsyncEntityProducer("Hi there")),
+ AsyncEntityProducers.create("Hi there")),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
final Message<HttpResponse, String> result1 = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
index d7fc2a6..0403259 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http2IntegrationTest.java
@@ -94,7 +94,7 @@ import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.HandlerFactory;
import org.apache.hc.core5.http.nio.ResponseChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
@@ -594,7 +594,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
context, new BasicPushProducer(new MultiLineEntityProducer("Pushing lots of stuff", 500)));
responseTrigger.submitResponse(new BasicResponseProducer(
HttpStatus.SC_OK,
- new BasicAsyncEntityProducer("Hi there")), context);
+ AsyncEntityProducers.create("Hi there")), context);
}
};
}
@@ -674,7 +674,7 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
responseTrigger.pushPromise(
new BasicHttpRequest(Methods.GET, createRequestURI(serverEndpoint, "/stuff")),
- context, new BasicPushProducer(new BasicAsyncEntityProducer("Pushing all sorts of stuff")) {
+ context, new BasicPushProducer(AsyncEntityProducers.create("Pushing all sorts of stuff")) {
@Override
public void failed(final Exception cause) {
@@ -694,9 +694,9 @@ public class Http2IntegrationTest extends InternalHttp2ServerTestBase {
}
});
- responseTrigger.submitResponse(new BasicResponseProducer(
- HttpStatus.SC_OK,
- new BasicAsyncEntityProducer("Hi there")), context);
+ responseTrigger.submitResponse(
+ new BasicResponseProducer(HttpStatus.SC_OK, AsyncEntityProducers.create("Hi there")),
+ context);
}
};
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
index 9ecc6af..5282a3a 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/SingleLineResponseHandler.java
@@ -37,7 +37,7 @@ import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.BasicRequestConsumer;
import org.apache.hc.core5.http.nio.BasicResponseProducer;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -61,7 +61,7 @@ public class SingleLineResponseHandler extends BasicServerExchangeHandler<Messag
final ResponseTrigger responseTrigger,
final HttpContext context) throws HttpException, IOException {
responseTrigger.submitResponse(new BasicResponseProducer(
- HttpStatus.SC_OK, new BasicAsyncEntityProducer(message)), context);
+ HttpStatus.SC_OK, AsyncEntityProducers.create(message)), context);
}
}
);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityTemplate.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityTemplate.java
index c76fcd9..2abfa15 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityTemplate.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityTemplate.java
@@ -36,10 +36,12 @@ import java.io.OutputStream;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.io.IOCallback;
import org.apache.hc.core5.util.Args;
/**
- * Entity that delegates the process of content generation to a {@link HttpContentProducer}.
+ * Entity that delegates the process of content generation to a {@link IOCallback}
+ * with {@link OutputStream} as output sink.
*
* @since 4.0
*/
@@ -47,14 +49,14 @@ import org.apache.hc.core5.util.Args;
public final class EntityTemplate extends AbstractHttpEntity {
private final long contentLength;
- private final HttpContentProducer contentProducer;
+ private final IOCallback<OutputStream> callback;
public EntityTemplate(
final long contentLength, final ContentType contentType, final String contentEncoding,
- final HttpContentProducer contentProducer) {
+ final IOCallback<OutputStream> callback) {
super(contentType, contentEncoding);
this.contentLength = contentLength;
- this.contentProducer = Args.notNull(contentProducer, "Content producer");
+ this.callback = Args.notNull(callback, "I/O callback");
}
@Override
@@ -77,7 +79,7 @@ public final class EntityTemplate extends AbstractHttpEntity {
@Override
public void writeTo(final OutputStream outStream) throws IOException {
Args.notNull(outStream, "Output stream");
- this.contentProducer.writeTo(outStream);
+ this.callback.execute(outStream);
}
@Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityUtils.java
index 5dd89da..ca37f5f 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EntityUtils.java
@@ -244,7 +244,7 @@ public final class EntityUtils {
public static List<NameValuePair> parse(final HttpEntity entity) throws IOException {
Args.notNull(entity, "HTTP entity");
final ContentType contentType = ContentType.parse(entity.getContentType());
- if (contentType == null || !contentType.getMimeType().equalsIgnoreCase(URLEncodedUtils.CONTENT_TYPE)) {
+ if (!ContentType.APPLICATION_FORM_URLENCODED.isSameMimeType(contentType)) {
return Collections.emptyList();
}
final long len = entity.getContentLength();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java
new file mode 100644
index 0000000..5f5a29f
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java
@@ -0,0 +1,224 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.io.entity;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.GZIPOutputStream;
+
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.io.IOCallback;
+import org.apache.hc.core5.net.URLEncodedUtils;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * {HttpEntity} factory methods.
+ *
+ * @since 5.0
+ */
+public final class HttpEntities {
+
+ private HttpEntities() {
+ }
+
+ public static HttpEntity create(final String content, final ContentType contentType) {
+ return new StringEntity(content, contentType);
+ }
+
+ public static HttpEntity create(final String content, final Charset charset) {
+ return new StringEntity(content, ContentType.TEXT_PLAIN.withCharset(charset));
+ }
+
+ public static HttpEntity create(final String content) {
+ return new StringEntity(content, ContentType.TEXT_PLAIN);
+ }
+
+ public static HttpEntity create(final byte[] content, final ContentType contentType) {
+ return new ByteArrayEntity(content, contentType);
+ }
+
+ public static HttpEntity create(final File content, final ContentType contentType) {
+ return new FileEntity(content, contentType);
+ }
+
+ public static HttpEntity create(final Serializable serializable, final ContentType contentType) {
+ return new SerializableEntity(serializable, contentType);
+ }
+
+ public static HttpEntity createUrlEncoded(
+ final Iterable <? extends NameValuePair> parameters, final Charset charset) {
+ final ContentType contentType = charset != null ?
+ ContentType.APPLICATION_FORM_URLENCODED.withCharset(charset) :
+ ContentType.APPLICATION_FORM_URLENCODED;
+ return create(URLEncodedUtils.format(parameters, contentType.getCharset()), contentType);
+ }
+
+ public static HttpEntity create(final IOCallback<OutputStream> callback, final ContentType contentType) {
+ return new EntityTemplate(-1, contentType, null, callback);
+ }
+
+ public static HttpEntity gzip(final HttpEntity entity) {
+ return new HttpEntityWrapper(entity) {
+
+ @Override
+ public String getContentEncoding() {
+ return "gzip";
+ }
+
+ @Override
+ public long getContentLength() {
+ return -1;
+ }
+
+ @Override
+ public InputStream getContent() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeTo(final OutputStream outStream) throws IOException {
+ Args.notNull(outStream, "Output stream");
+ final GZIPOutputStream gzip = new GZIPOutputStream(outStream);
+ super.writeTo(gzip);
+ // Only close output stream if the wrapped entity has been
+ // successfully written out
+ gzip.close();
+ }
+
+ };
+ }
+
+ public static HttpEntity createGzipped(final String content, final ContentType contentType) {
+ return gzip(create(content, contentType));
+ }
+
+ public static HttpEntity createGzipped(final String content, final Charset charset) {
+ return gzip(create(content, charset));
+ }
+
+ public static HttpEntity createGzipped(final String content) {
+ return gzip(create(content));
+ }
+
+ public static HttpEntity createGzipped(final byte[] content, final ContentType contentType) {
+ return gzip(create(content, contentType));
+ }
+
+ public static HttpEntity createGzipped(final File content, final ContentType contentType) {
+ return gzip(create(content, contentType));
+ }
+
+ public static HttpEntity createGzipped(final Serializable serializable, final ContentType contentType) {
+ return gzip(create(serializable, contentType));
+ }
+
+ public static HttpEntity createGzipped(final IOCallback<OutputStream> callback, final ContentType contentType) {
+ return gzip(create(callback, contentType));
+ }
+
+ public static HttpEntity withTrailers(final HttpEntity entity, final Header... trailers) {
+ return new HttpEntityWrapper(entity) {
+
+ @Override
+ public boolean isChunked() {
+ // Must be chunk coded
+ return true;
+ }
+
+ @Override
+ public long getContentLength() {
+ return -1;
+ }
+
+ @Override
+ public Supplier<List<? extends Header>> getTrailers() {
+ return new Supplier<List<? extends Header>>() {
+
+ @Override
+ public List<? extends Header> get() {
+ return Arrays.asList(trailers);
+ }
+
+ };
+ }
+
+ @Override
+ public Set<String> getTrailerNames() {
+ final Set<String> names = new LinkedHashSet<>();
+ for (final Header trailer: trailers) {
+ names.add(trailer.getName());
+ }
+ return names;
+ }
+
+ };
+ }
+
+ public static HttpEntity create(final String content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static HttpEntity create(final String content, final Charset charset, final Header... trailers) {
+ return withTrailers(create(content, charset), trailers);
+ }
+
+ public static HttpEntity create(final String content, final Header... trailers) {
+ return withTrailers(create(content), trailers);
+ }
+
+ public static HttpEntity create(final byte[] content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static HttpEntity create(final File content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static HttpEntity create(
+ final Serializable serializable, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(serializable, contentType), trailers);
+ }
+
+ public static HttpEntity create(
+ final IOCallback<OutputStream> callback, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(callback, contentType), trailers);
+ }
+
+}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWrapper.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWrapper.java
index a3ede51..4873eaf 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWrapper.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWrapper.java
@@ -41,10 +41,8 @@ import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.util.Args;
/**
- * Base class for wrapping entities.
- * Keeps a {@link #wrappedEntity wrappedEntity} and delegates all
- * calls to it. Implementations of wrapping entities can derive
- * from this class and need to override only those methods that
+ * Base class for wrapping entities that delegates all calls to the wrapped entity.
+ * Implementations can derive from this class and override only those methods that
* should not be delegated to the wrapped entity.
*
* @since 4.0
@@ -124,7 +122,7 @@ public class HttpEntityWrapper implements HttpEntity {
@Override
public String toString() {
- return super.toString() + "[" + wrappedEntity + "]";
+ return "Wrapper [" + wrappedEntity + "]";
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/BasicResponseProducer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/BasicResponseProducer.java
index c98b9ee..087ebae 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/BasicResponseProducer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/BasicResponseProducer.java
@@ -33,7 +33,7 @@ import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.message.BasicHttpResponse;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.Args;
@@ -63,7 +63,7 @@ public class BasicResponseProducer implements AsyncResponseProducer {
}
public BasicResponseProducer(final HttpResponse response, final String message, final ContentType contentType) {
- this(response, new BasicAsyncEntityProducer(message, contentType));
+ this(response, AsyncEntityProducers.create(message, contentType));
}
public BasicResponseProducer(final HttpResponse response, final String message) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWithTrailers.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducerWrapper.java
similarity index 52%
rename from httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWithTrailers.java
rename to httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducerWrapper.java
index 4775451..834669d 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntityWithTrailers.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducerWrapper.java
@@ -25,107 +25,87 @@
*
*/
-package org.apache.hc.core5.http.io.entity;
+package org.apache.hc.core5.http.nio.entity;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Set;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.util.Args;
/**
- * Wrapping entity that also includes trailers.
+ * Base class for wrapping entity producers that delegates all calls to the wrapped producer.
+ * Implementations can derive from this class and override only those methods that
+ * should not be delegated to the wrapped producer.
*
* @since 5.0
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
-public class HttpEntityWithTrailers implements HttpEntity {
+public class AsyncEntityProducerWrapper implements AsyncEntityProducer {
- private final HttpEntity wrappedEntity;
- private final List<Header> trailers;
+ private final AsyncEntityProducer wrappedEntityProducer;
- /**
- * Creates a new entity wrapper.
- */
- public HttpEntityWithTrailers(final HttpEntity wrappedEntity, final Header... trailers) {
+ public AsyncEntityProducerWrapper(final AsyncEntityProducer wrappedEntityProducer) {
super();
- this.wrappedEntity = Args.notNull(wrappedEntity, "Wrapped entity");
- this.trailers = Arrays.asList(trailers);
+ this.wrappedEntityProducer = Args.notNull(wrappedEntityProducer, "Wrapped entity producer");
}
@Override
public boolean isRepeatable() {
- return wrappedEntity.isRepeatable();
+ return wrappedEntityProducer.isRepeatable();
}
@Override
public boolean isChunked() {
- return true;
+ return wrappedEntityProducer.isChunked();
}
@Override
public long getContentLength() {
- return wrappedEntity.getContentLength();
+ return wrappedEntityProducer.getContentLength();
}
@Override
public String getContentType() {
- return wrappedEntity.getContentType();
+ return wrappedEntityProducer.getContentType();
}
@Override
public String getContentEncoding() {
- return wrappedEntity.getContentEncoding();
+ return wrappedEntityProducer.getContentEncoding();
}
@Override
- public InputStream getContent()
- throws IOException {
- return wrappedEntity.getContent();
+ public Set<String> getTrailerNames() {
+ return wrappedEntityProducer.getTrailerNames();
}
@Override
- public void writeTo(final OutputStream outStream)
- throws IOException {
- wrappedEntity.writeTo(outStream);
+ public int available() {
+ return wrappedEntityProducer.available();
}
@Override
- public boolean isStreaming() {
- return wrappedEntity.isStreaming();
+ public void produce(final DataStreamChannel channel) throws IOException {
+ wrappedEntityProducer.produce(channel);
}
@Override
- public Supplier<List<? extends Header>> getTrailers() {
- return new Supplier<List<? extends Header>>() {
- @Override
- public List<? extends Header> get() {
- return trailers;
- }
- };
+ public void failed(final Exception cause) {
+ wrappedEntityProducer.failed(cause);
}
@Override
- public Set<String> getTrailerNames() {
- final Set<String> names = new LinkedHashSet<>();
- for (final Header trailer: trailers) {
- names.add(trailer.getName());
- }
- return names;
+ public void releaseResources() {
+ wrappedEntityProducer.releaseResources();
}
@Override
- public void close() throws IOException {
- wrappedEntity.close();
+ public String toString() {
+ return "Wrapper [" + wrappedEntityProducer + "]";
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducers.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducers.java
new file mode 100644
index 0000000..4fca51d
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/AsyncEntityProducers.java
@@ -0,0 +1,235 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.nio.entity;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hc.core5.function.Callback;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+import org.apache.hc.core5.http.nio.StreamChannel;
+import org.apache.hc.core5.net.URLEncodedUtils;
+
+/**
+ * {AsyncEntityProducer} factory methods.
+ *
+ * @since 5.0
+ */
+public final class AsyncEntityProducers {
+
+ private AsyncEntityProducers() {
+ }
+
+ public static AsyncEntityProducer create(final String content, final ContentType contentType) {
+ return new BasicAsyncEntityProducer(content, contentType);
+ }
+
+ public static AsyncEntityProducer create(final String content, final Charset charset) {
+ return new BasicAsyncEntityProducer(content, ContentType.TEXT_PLAIN.withCharset(charset));
+ }
+
+ public static AsyncEntityProducer create(final String content) {
+ return new BasicAsyncEntityProducer(content, ContentType.TEXT_PLAIN);
+ }
+
+ public static AsyncEntityProducer create(final byte[] content, final ContentType contentType) {
+ return new BasicAsyncEntityProducer(content, contentType);
+ }
+
+ public static AsyncEntityProducer create(final File content, final ContentType contentType) {
+ return new FileEntityProducer(content, contentType);
+ }
+
+ public static AsyncEntityProducer createUrlEncoded(
+ final Iterable <? extends NameValuePair> parameters, final Charset charset) {
+ final ContentType contentType = charset != null ?
+ ContentType.APPLICATION_FORM_URLENCODED.withCharset(charset) :
+ ContentType.APPLICATION_FORM_URLENCODED;
+ return create(URLEncodedUtils.format(parameters, contentType.getCharset()), contentType);
+ }
+
+ public static AsyncEntityProducer createBinary(
+ final Callback<StreamChannel<ByteBuffer>> callback,
+ final ContentType contentType) {
+ return new AbstractBinAsyncEntityProducer(0, contentType) {
+
+ @Override
+ protected int availableData() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ protected void produceData(final StreamChannel<ByteBuffer> channel) throws IOException {
+ callback.execute(channel);
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return false;
+ }
+
+ @Override
+ public void failed(final Exception cause) {
+ }
+
+ };
+ }
+
+ public static AsyncEntityProducer createText(
+ final Callback<StreamChannel<CharBuffer>> callback,
+ final ContentType contentType) {
+ return new AbstractCharAsyncEntityProducer(0, 4096, contentType) {
+
+ @Override
+ protected int availableData() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ protected void produceData(final StreamChannel<CharBuffer> channel) throws IOException {
+ callback.execute(channel);
+ }
+
+ @Override
+ public boolean isRepeatable() {
+ return false;
+ }
+
+ @Override
+ public void failed(final Exception cause) {
+ }
+
+ };
+ }
+
+ public static AsyncEntityProducer withTrailers(final AsyncEntityProducer entity, final Header... trailers) {
+ return new AsyncEntityProducerWrapper(entity) {
+
+ @Override
+ public boolean isChunked() {
+ // Must be chunk coded
+ return true;
+ }
+
+ @Override
+ public long getContentLength() {
+ return -1;
+ }
+
+ @Override
+ public Set<String> getTrailerNames() {
+ final Set<String> names = new LinkedHashSet<>();
+ for (final Header trailer: trailers) {
+ names.add(trailer.getName());
+ }
+ return names;
+ }
+
+ @Override
+ public void produce(final DataStreamChannel channel) throws IOException {
+ super.produce(new DataStreamChannel() {
+
+ @Override
+ public void requestOutput() {
+ channel.requestOutput();
+ }
+
+ @Override
+ public int write(final ByteBuffer src) throws IOException {
+ return channel.write(src);
+ }
+
+ @Override
+ public void endStream(final List<? extends Header> p) throws IOException {
+ final List<Header> allTrailers;
+ if (p != null && !p.isEmpty()) {
+ allTrailers = new ArrayList<>(p);
+ allTrailers.addAll(Arrays.asList(trailers));
+ } else {
+ allTrailers = Arrays.asList(trailers);
+ }
+ channel.endStream(allTrailers);
+ }
+
+ @Override
+ public void endStream() throws IOException {
+ channel.endStream();
+ }
+
+ });
+ }
+ };
+ }
+
+ public static AsyncEntityProducer create(final String content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static AsyncEntityProducer create(final String content, final Charset charset, final Header... trailers) {
+ return withTrailers(create(content, charset), trailers);
+ }
+
+ public static AsyncEntityProducer create(final String content, final Header... trailers) {
+ return withTrailers(create(content), trailers);
+ }
+
+ public static AsyncEntityProducer create(final byte[] content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static AsyncEntityProducer create(final File content, final ContentType contentType, final Header... trailers) {
+ return withTrailers(create(content, contentType), trailers);
+ }
+
+ public static AsyncEntityProducer createBinary(
+ final Callback<StreamChannel<ByteBuffer>> callback,
+ final ContentType contentType,
+ final Header... trailers) {
+ return withTrailers(createBinary(callback, contentType), trailers);
+ }
+
+ public static AsyncEntityProducer createText(
+ final Callback<StreamChannel<CharBuffer>> callback,
+ final ContentType contentType,
+ final Header... trailers) {
+ return withTrailers(createText(callback, contentType), trailers);
+ }
+
+}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncServerAuthFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncServerAuthFilter.java
index 1ee3713..b056692 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncServerAuthFilter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncServerAuthFilter.java
@@ -47,7 +47,7 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer;
import org.apache.hc.core5.http.nio.AsyncFilterChain;
import org.apache.hc.core5.http.nio.AsyncFilterHandler;
import org.apache.hc.core5.http.nio.CapacityChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
@@ -110,7 +110,7 @@ public abstract class AbstractAsyncServerAuthFilter<T> implements AsyncFilterHan
* @return the response content entity.
*/
protected AsyncEntityProducer generateResponseContent(final HttpResponse unauthorized) {
- return new BasicAsyncEntityProducer("Unauthorized");
+ return AsyncEntityProducers.create("Unauthorized");
}
@Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/ImmediateResponseExchangeHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/ImmediateResponseExchangeHandler.java
index 2511d4c..9903af5 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/ImmediateResponseExchangeHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/ImmediateResponseExchangeHandler.java
@@ -30,7 +30,6 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
-import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
@@ -43,7 +42,7 @@ import org.apache.hc.core5.http.nio.BasicResponseProducer;
import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.ResponseChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.Args;
@@ -63,7 +62,7 @@ public final class ImmediateResponseExchangeHandler implements AsyncServerExchan
}
public ImmediateResponseExchangeHandler(final HttpResponse response, final String message) {
- this(new BasicResponseProducer(response, new BasicAsyncEntityProducer(message, ContentType.TEXT_PLAIN)));
+ this(new BasicResponseProducer(response, AsyncEntityProducers.create(message)));
}
public ImmediateResponseExchangeHandler(final int status, final String message) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
index f45fa83..04ba5c3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
@@ -46,7 +46,7 @@ import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.HandlerFactory;
import org.apache.hc.core5.http.nio.ResponseChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.Args;
@@ -147,7 +147,7 @@ public final class TerminalAsyncServerFilter implements AsyncFilterHandler {
}, context);
return exchangeHandler;
}
- responseTrigger.submitResponse(new BasicHttpResponse(HttpStatus.SC_NOT_FOUND), new BasicAsyncEntityProducer("Not found"));
+ responseTrigger.submitResponse(new BasicHttpResponse(HttpStatus.SC_NOT_FOUND), AsyncEntityProducers.create("Not found"));
return null;
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpContentProducer.java b/httpcore5/src/main/java/org/apache/hc/core5/io/IOCallback.java
similarity index 80%
rename from httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpContentProducer.java
rename to httpcore5/src/main/java/org/apache/hc/core5/io/IOCallback.java
index 742426b..24fb294 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpContentProducer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/io/IOCallback.java
@@ -25,20 +25,17 @@
*
*/
-package org.apache.hc.core5.http.io.entity;
+package org.apache.hc.core5.io;
import java.io.IOException;
-import java.io.OutputStream;
/**
- * An abstract entity content producer.
- *<p>Content producers are expected to be able to produce their
- * content multiple times</p>
+ * Abstract I/O callback.
*
* @since 5.0
*/
-public interface HttpContentProducer {
+public interface IOCallback<T> {
- void writeTo(OutputStream outStream) throws IOException;
+ void execute(T object) throws IOException;
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
index 7cab723..f9c999c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URLEncodedUtils.java
@@ -51,11 +51,6 @@ import org.apache.hc.core5.util.Args;
*/
public class URLEncodedUtils {
- /**
- * The default HTML form content type.
- */
- public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
-
private static final char QP_SEP_A = '&';
private static final char QP_SEP_S = ';';
private static final String NAME_VALUE_SEPARATOR = "=";
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
index f8b70ad..6da0fc6 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
@@ -33,7 +33,6 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpConnection;
@@ -55,7 +54,7 @@ import org.apache.hc.core5.http.nio.BasicResponseConsumer;
import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
import org.apache.hc.core5.http.nio.RequestChannel;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
@@ -123,7 +122,7 @@ public class AsyncFullDuplexClientExample {
final URI requestUri = new URI("http://httpbin.org/post");
final BasicRequestProducer requestProducer = new BasicRequestProducer(
- Methods.POST.name(), requestUri, new BasicAsyncEntityProducer("stuff", ContentType.TEXT_PLAIN));
+ Methods.POST.name(), requestUri, AsyncEntityProducers.create("stuff"));
final BasicResponseConsumer<String> responseConsumer = new BasicResponseConsumer<>(
new StringAsyncEntityConsumer());
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
index 1d8055e..828f849 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
@@ -31,7 +31,6 @@ import java.net.InetSocketAddress;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
@@ -51,7 +50,7 @@ import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.BasicRequestConsumer;
import org.apache.hc.core5.http.nio.BasicResponseProducer;
-import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.support.AbstractAsyncServerAuthFilter;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -124,7 +123,7 @@ public class AsyncServerFilterExample {
if (request.getRequestUri().equals("/back-door")) {
responseTrigger.submitResponse(
new BasicHttpResponse(HttpStatus.SC_OK),
- new BasicAsyncEntityProducer("Welcome", ContentType.TEXT_PLAIN));
+ AsyncEntityProducers.create("Welcome"));
return null;
}
return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
@@ -171,9 +170,9 @@ public class AsyncServerFilterExample {
final ResponseTrigger responseTrigger,
final HttpContext context) throws HttpException, IOException {
// do something useful
- responseTrigger.submitResponse(new BasicResponseProducer(
- HttpStatus.SC_OK,
- new BasicAsyncEntityProducer("Hello", ContentType.TEXT_PLAIN)), context);
+ responseTrigger.submitResponse(
+ new BasicResponseProducer(HttpStatus.SC_OK, AsyncEntityProducers.create("Hello")),
+ context);
}
})
.create();
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
index 4b33caf..5430bfc 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
@@ -27,7 +27,8 @@
package org.apache.hc.core5.http.examples;
-import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@@ -44,14 +45,14 @@ import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
import org.apache.hc.core5.http.io.SocketConfig;
-import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.InputStreamEntity;
-import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.HttpEntities;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
+import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.message.RequestLine;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.io.IOCallback;
import org.apache.hc.core5.util.Timeout;
/**
@@ -92,17 +93,26 @@ public class ClassicPostExecutionExample {
final HttpHost target = new HttpHost("httpbin.org");
final HttpEntity[] requestBodies = {
- new StringEntity(
+ HttpEntities.create(
"This is the first test request",
- ContentType.create("text/plain", StandardCharsets.UTF_8)),
- new ByteArrayEntity(
+ ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)),
+ HttpEntities.create(
"This is the second test request".getBytes(StandardCharsets.UTF_8),
ContentType.APPLICATION_OCTET_STREAM),
- new InputStreamEntity(
- new ByteArrayInputStream(
- "This is the third test request (will be chunked)"
- .getBytes(StandardCharsets.UTF_8)),
- ContentType.APPLICATION_OCTET_STREAM)
+ HttpEntities.create(new IOCallback<OutputStream>() {
+
+ @Override
+ public void execute(final OutputStream outStream) throws IOException {
+ outStream.write(("This is the third test request " +
+ "(streaming)").getBytes(StandardCharsets.UTF_8));
+ }
+
+ }, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)),
+ HttpEntities.create(
+ "This is the fourth test request " +
+ "(streaming with trailers)",
+ ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8),
+ new BasicHeader("trailer1","And goodbye"))
};
final String requestUri = "/post";
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostWithTrailersExecutionExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostWithTrailersExecutionExample.java
deleted file mode 100644
index 7bb487b..0000000
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostWithTrailersExecutionExample.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.core5.http.examples;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.Methods;
-import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
-import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
-import org.apache.hc.core5.http.io.SocketConfig;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.HttpEntityWithTrailers;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.protocol.HttpCoreContext;
-import org.apache.hc.core5.util.Timeout;
-
-/**
- * Example of POST request with trailers execution using classic I/O.
- */
-public class ClassicPostWithTrailersExecutionExample {
- public static void main(final String[] args) throws Exception {
- final HttpRequester httpRequester = RequesterBootstrap.bootstrap()
- .setSocketConfig(SocketConfig.custom()
- .setSoTimeout(5, TimeUnit.SECONDS)
- .build())
- .create();
-
- final HttpCoreContext coreContext = HttpCoreContext.create();
- final HttpHost target = new HttpHost("httpbin.org");
-
- final String requestUri = "/post";
- final ClassicHttpRequest request = new BasicClassicHttpRequest(Methods.POST, target, requestUri);
- final HttpEntity requestBody = new HttpEntityWithTrailers(
- new StringEntity("Chunked message with trailers", ContentType.TEXT_PLAIN),
- new BasicHeader("t1","Hello world"));
- request.setEntity(requestBody);
-
- System.out.println(">> Request URI: " + request.getUri());
- try (ClassicHttpResponse response = httpRequester.execute(target, request, Timeout.ofSeconds(5), coreContext)) {
- System.out.println(requestUri + "->" + response.getCode());
- System.out.println(EntityUtils.toString(response.getEntity()));
- System.out.println("==============");
- }
- }
-
-}
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestEntityUtils.java b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestEntityUtils.java
index 2fe5cbf..e8a3611 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestEntityUtils.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestEntityUtils.java
@@ -230,7 +230,7 @@ public class TestEntityUtils {
Assert.assertEquals("russian=%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" +
"&swiss=Gr%C3%BCezi_z%C3%A4m%C3%A4", s);
final StringEntity entity = new StringEntity(s,
- ContentType.create(URLEncodedUtils.CONTENT_TYPE, StandardCharsets.UTF_8));
+ ContentType.APPLICATION_FORM_URLENCODED.withCharset(StandardCharsets.UTF_8));
final List<NameValuePair> result = EntityUtils.parse(entity);
Assert.assertEquals(2, result.size());
assertNameValuePair(result.get(0), "russian", ru_hello);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestMessageSupport.java b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestMessageSupport.java
index 0df4c32..9909a09 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestMessageSupport.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/message/TestMessageSupport.java
@@ -32,10 +32,10 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpMessage;
-import org.apache.hc.core5.http.io.entity.HttpEntityWithTrailers;
-import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.HttpEntities;
import org.apache.hc.core5.util.CharArrayBuffer;
import org.junit.Assert;
import org.junit.Test;
@@ -103,8 +103,7 @@ public class TestMessageSupport {
@Test
public void testAddContentHeaders() throws Exception {
- final HttpEntityWithTrailers entity = new HttpEntityWithTrailers(
- new StringEntity("some stuff with trailers", StandardCharsets.US_ASCII),
+ final HttpEntity entity = HttpEntities.create("some stuff with trailers", StandardCharsets.US_ASCII,
new BasicHeader("z", "this"), new BasicHeader("b", "that"), new BasicHeader("a", "this and that"));
final HttpMessage message = new BasicHttpResponse(200);
MessageSupport.addTrailerHeader(message, entity);
@@ -121,8 +120,7 @@ public class TestMessageSupport {
@Test
public void testContentHeadersAlreadyPresent() throws Exception {
- final HttpEntityWithTrailers entity = new HttpEntityWithTrailers(
- new StringEntity("some stuff with trailers", StandardCharsets.US_ASCII),
+ final HttpEntity entity = HttpEntities.create("some stuff with trailers", StandardCharsets.US_ASCII,
new BasicHeader("z", "this"), new BasicHeader("b", "that"), new BasicHeader("a", "this and that"));
final HttpMessage message = new BasicHttpResponse(200);
message.addHeader(HttpHeaders.TRAILER, "a, a, a");
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java b/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java
index b8bce7b..c4d24d2 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java
@@ -40,7 +40,7 @@ import org.apache.hc.core5.http.Methods;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.impl.io.EmptyInputStream;
import org.apache.hc.core5.http.io.entity.BasicHttpEntity;
-import org.apache.hc.core5.http.io.entity.HttpEntityWithTrailers;
+import org.apache.hc.core5.http.io.entity.HttpEntities;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
@@ -299,7 +299,7 @@ public class TestStandardInterceptors {
public void testRequestContentEntityWithTrailers() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final BasicClassicHttpRequest request = new BasicClassicHttpRequest(Methods.POST, "/");
- request.setEntity(new HttpEntityWithTrailers(new StringEntity("whatever", StandardCharsets.US_ASCII),
+ request.setEntity(HttpEntities.create("whatever", StandardCharsets.US_ASCII,
new BasicHeader("h1", "this"), new BasicHeader("h1", "that"), new BasicHeader("h2", "this and that")));
final RequestContent interceptor = new RequestContent();
@@ -888,7 +888,7 @@ public class TestStandardInterceptors {
public void testResponseContentEntityWithTrailers() throws Exception {
final HttpContext context = new BasicHttpContext(null);
final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK");
- response.setEntity(new HttpEntityWithTrailers(new StringEntity("whatever", StandardCharsets.US_ASCII),
+ response.setEntity(HttpEntities.create("whatever", StandardCharsets.US_ASCII,
new BasicHeader("h1", "this"), new BasicHeader("h1", "that"), new BasicHeader("h2", "this and that")));
final ResponseContent interceptor = new ResponseContent();