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 2017/08/25 17:03:33 UTC
httpcomponents-core git commit: Fixed propagation of entity details
of incoming HTTP/1.1 messages by non-blocking HTTP/1.1 stream duplexer
Repository: httpcomponents-core
Updated Branches:
refs/heads/master bf041e342 -> c3472dfb1
Fixed propagation of entity details of incoming HTTP/1.1 messages by non-blocking HTTP/1.1 stream duplexer
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/c3472dfb
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/c3472dfb
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/c3472dfb
Branch: refs/heads/master
Commit: c3472dfb1ad303f089a858cc084322e8762cb587
Parents: bf041e3
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Aug 25 15:17:59 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Aug 25 16:11:11 2017 +0200
----------------------------------------------------------------------
.../impl/nio/ClientHttp2StreamHandler.java | 4 +-
.../impl/nio/ClientPushHttp2StreamHandler.java | 4 +-
.../impl/nio/ServerHttp2StreamHandler.java | 4 +-
.../core5/testing/nio/Http1IntegrationTest.java | 7 +-
.../core5/http/impl/IncomingEntityDetails.java | 90 ++++++++++++++++++++
.../hc/core5/http/impl/LazyEntityDetails.java | 84 ------------------
.../impl/nio/AbstractHttp1StreamDuplexer.java | 47 ++++++++--
.../impl/nio/ClientHttp1StreamDuplexer.java | 44 +++++-----
.../http/impl/nio/ClientHttp1StreamHandler.java | 6 +-
.../impl/nio/ServerHttp1StreamDuplexer.java | 34 ++++----
.../http/impl/nio/ServerHttp1StreamHandler.java | 6 +-
11 files changed, 181 insertions(+), 149 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
index 4bc0987..b3467c0 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttp2StreamHandler.java
@@ -41,7 +41,7 @@ import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
+import org.apache.hc.core5.http.impl.IncomingEntityDetails;
import org.apache.hc.core5.http.impl.nio.MessageState;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
import org.apache.hc.core5.http.nio.DataStreamChannel;
@@ -199,7 +199,7 @@ class ClientHttp2StreamHandler implements Http2StreamHandler {
return;
}
- final EntityDetails entityDetails = endStream ? null : new LazyEntityDetails(response);
+ final EntityDetails entityDetails = endStream ? null : new IncomingEntityDetails(response, -1);
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
httpProcessor.process(response, entityDetails, context);
connMetrics.incrementResponseCount();
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
index abb1f94..6b52010 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
@@ -39,7 +39,7 @@ import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
+import org.apache.hc.core5.http.impl.IncomingEntityDetails;
import org.apache.hc.core5.http.impl.nio.MessageState;
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
import org.apache.hc.core5.http.nio.HandlerFactory;
@@ -126,7 +126,7 @@ class ClientPushHttp2StreamHandler implements Http2StreamHandler {
Asserts.notNull(exchangeHandler, "Exchange handler");
final HttpResponse response = DefaultH2ResponseConverter.INSTANCE.convert(headers);
- final EntityDetails entityDetails = endStream ? null : new LazyEntityDetails(request);
+ final EntityDetails entityDetails = endStream ? null : new IncomingEntityDetails(request, -1);
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
httpProcessor.process(response, entityDetails, context);
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
index 52ab4a2..8349c9c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
@@ -40,7 +40,7 @@ import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
+import org.apache.hc.core5.http.impl.IncomingEntityDetails;
import org.apache.hc.core5.http.impl.nio.MessageState;
import org.apache.hc.core5.http.nio.AsyncPushProducer;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
@@ -182,7 +182,7 @@ public class ServerHttp2StreamHandler implements Http2StreamHandler {
requestState = endStream ? MessageState.COMPLETE : MessageState.BODY;
final HttpRequest request = DefaultH2RequestConverter.INSTANCE.convert(headers);
- final EntityDetails requestEntityDetails = endStream ? null : new LazyEntityDetails(request);
+ final EntityDetails requestEntityDetails = endStream ? null : new IncomingEntityDetails(request, -1);
final AsyncServerExchangeHandler handler;
try {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
----------------------------------------------------------------------
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 2ad7661..fd6ac50 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
@@ -1402,16 +1402,15 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
streamListener) {
@Override
- protected ContentEncoder handleOutgoingMessage(
- final HttpResponse response,
+ protected ContentEncoder createContentEncoder(
+ final long len,
final WritableByteChannel channel,
final SessionOutputBuffer buffer,
final BasicHttpTransportMetrics metrics) throws HttpException {
- final long len = outgoingContentStrategy.determineLength(response);
if (len == ContentLengthStrategy.CHUNKED) {
return new BrokenChunkEncoder(channel, buffer, metrics);
} else {
- return super.handleOutgoingMessage(response, channel, buffer, metrics);
+ return super.createContentEncoder(len, channel, buffer, metrics);
}
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/IncomingEntityDetails.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/IncomingEntityDetails.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/IncomingEntityDetails.java
new file mode 100644
index 0000000..010132c
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/IncomingEntityDetails.java
@@ -0,0 +1,90 @@
+/*
+ * ====================================================================
+ * 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.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.MessageHeaders;
+import org.apache.hc.core5.http.message.MessageSupport;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * HTTP message entity details.
+ *
+ * @since 5.0
+ */
+public class IncomingEntityDetails implements EntityDetails {
+
+ private final MessageHeaders message;
+ private final long contentLength;
+
+ public IncomingEntityDetails(final MessageHeaders message, final long contentLength) {
+ this.message = Args.notNull(message, "Message");
+ this.contentLength = contentLength;
+ }
+
+ public IncomingEntityDetails(final MessageHeaders message) {
+ this(message, -1);
+ }
+
+ @Override
+ public long getContentLength() {
+ return contentLength;
+ }
+
+ @Override
+ public String getContentType() {
+ final Header h = message.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+ return h != null ? h.getValue() : null;
+ }
+
+ @Override
+ public String getContentEncoding() {
+ final Header h = message.getFirstHeader(HttpHeaders.CONTENT_ENCODING);
+ return h != null ? h.getValue() : null;
+ }
+
+ @Override
+ public boolean isChunked() {
+ return contentLength < 0;
+ }
+
+ @Override
+ public Set<String> getTrailerNames() {
+ final Header h = message.getFirstHeader(HttpHeaders.TRAILER);
+ if (h == null) {
+ return Collections.emptySet();
+ }
+ return MessageSupport.parseTokens(h);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/LazyEntityDetails.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/LazyEntityDetails.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/LazyEntityDetails.java
deleted file mode 100644
index 2babd44..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/LazyEntityDetails.java
+++ /dev/null
@@ -1,84 +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.impl;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.MessageHeaders;
-import org.apache.hc.core5.http.message.MessageSupport;
-import org.apache.hc.core5.util.Args;
-
-/**
- * HTTP message entity details.
- *
- * @since 5.0
- */
-public class LazyEntityDetails implements EntityDetails {
-
- private final MessageHeaders message;
-
- public LazyEntityDetails(final MessageHeaders message) {
- this.message = Args.notNull(message, "Message");
- }
-
- @Override
- public long getContentLength() {
- return -1;
- }
-
- @Override
- public String getContentType() {
- final Header h = message.getFirstHeader(HttpHeaders.CONTENT_TYPE);
- return h != null ? h.getValue() : null;
- }
-
- @Override
- public String getContentEncoding() {
- final Header h = message.getFirstHeader(HttpHeaders.CONTENT_TYPE);
- return h != null ? h.getValue() : null;
- }
-
- @Override
- public boolean isChunked() {
- return false;
- }
-
- @Override
- public Set<String> getTrailerNames() {
- final Header h = message.getFirstHeader(HttpHeaders.TRAILER);
- if (h == null) {
- return Collections.emptySet();
- }
- return MessageSupport.parseTokens(h);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
index f5e2018..e6aa31f 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
@@ -44,7 +44,9 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.ContentLengthStrategy;
import org.apache.hc.core5.http.EndpointDetails;
+import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpMessage;
@@ -56,6 +58,8 @@ import org.apache.hc.core5.http.impl.BasicEndpointDetails;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
import org.apache.hc.core5.http.impl.CharCodingSupport;
+import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
+import org.apache.hc.core5.http.impl.IncomingEntityDetails;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.ContentDecoder;
@@ -93,6 +97,8 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
private final BasicHttpConnectionMetrics connMetrics;
private final NHttpMessageParser<IncomingMessage> incomingMessageParser;
private final NHttpMessageWriter<OutgoingMessage> outgoingMessageWriter;
+ private final ContentLengthStrategy incomingContentStrategy;
+ private final ContentLengthStrategy outgoingContentStrategy;
private final ByteBuffer contentBuffer;
private final Lock outputLock;
private final AtomicInteger outputRequests;
@@ -109,7 +115,9 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
final H1Config h1Config,
final CharCodingConfig charCodingConfig,
final NHttpMessageParser<IncomingMessage> incomingMessageParser,
- final NHttpMessageWriter<OutgoingMessage> outgoingMessageWriter) {
+ final NHttpMessageWriter<OutgoingMessage> outgoingMessageWriter,
+ final ContentLengthStrategy incomingContentStrategy,
+ final ContentLengthStrategy outgoingContentStrategy) {
this.ioSession = Args.notNull(ioSession, "I/O session");
this.h1Config = h1Config != null ? h1Config : H1Config.DEFAULT;
final int bufferSize = this.h1Config.getBufferSize();
@@ -123,6 +131,10 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
this.connMetrics = new BasicHttpConnectionMetrics(inTransportMetrics, outTransportMetrics);
this.incomingMessageParser = incomingMessageParser;
this.outgoingMessageWriter = outgoingMessageWriter;
+ this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
+ DefaultContentLengthStrategy.INSTANCE;
+ this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
+ DefaultContentLengthStrategy.INSTANCE;
this.contentBuffer = ByteBuffer.allocate(this.h1Config.getBufferSize());
this.outputLock = new ReentrantLock();
this.outputRequests = new AtomicInteger(0);
@@ -161,16 +173,20 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
abstract void updateOutputMetrics(OutgoingMessage outgoingMessage, BasicHttpConnectionMetrics connMetrics);
- abstract void consumeHeader(IncomingMessage messageHead, boolean endStream) throws HttpException, IOException;
+ abstract void consumeHeader(IncomingMessage messageHead, EntityDetails entityDetails) throws HttpException, IOException;
- abstract ContentDecoder handleIncomingMessage(
- IncomingMessage incomingMessage,
+ abstract boolean handleIncomingMessage(IncomingMessage incomingMessage) throws HttpException;
+
+ abstract boolean handleOutgoingMessage(OutgoingMessage outgoingMessage) throws HttpException;
+
+ abstract ContentDecoder createContentDecoder(
+ long contentLength,
ReadableByteChannel channel,
SessionInputBuffer buffer,
BasicHttpTransportMetrics metrics) throws HttpException;
- abstract ContentEncoder handleOutgoingMessage(
- OutgoingMessage outgoingMessage,
+ abstract ContentEncoder createContentEncoder(
+ long contentLength,
WritableByteChannel channel,
SessionOutputBuffer buffer,
BasicHttpTransportMetrics metrics) throws HttpException;
@@ -253,8 +269,15 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
this.version = messageHead.getVersion();
updateInputMetrics(messageHead, connMetrics);
- final ContentDecoder contentDecoder = handleIncomingMessage(messageHead, ioSession.channel(), inbuf, inTransportMetrics);
- consumeHeader(messageHead, contentDecoder == null);
+ final ContentDecoder contentDecoder;
+ if (handleIncomingMessage(messageHead)) {
+ final long len = incomingContentStrategy.determineLength(messageHead);
+ contentDecoder = createContentDecoder(len, ioSession.channel(), inbuf, inTransportMetrics);
+ consumeHeader(messageHead, contentDecoder != null ? new IncomingEntityDetails(messageHead, len) : null);
+ } else {
+ consumeHeader(messageHead, null);
+ contentDecoder = null;
+ }
if (contentDecoder != null) {
incomingMessage = new Message<>(messageHead, contentDecoder);
break;
@@ -436,7 +459,13 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
outgoingMessageWriter.write(messageHead, outbuf);
updateOutputMetrics(messageHead, connMetrics);
if (!endStream) {
- final ContentEncoder contentEncoder = handleOutgoingMessage(messageHead, ioSession.channel(), outbuf, outTransportMetrics);
+ final ContentEncoder contentEncoder;
+ if (handleOutgoingMessage(messageHead)) {
+ final long len = outgoingContentStrategy.determineLength(messageHead);
+ contentEncoder = createContentEncoder(len, ioSession.channel(), outbuf, outTransportMetrics);
+ } else {
+ contentEncoder = null;
+ }
if (contentEncoder != null) {
outgoingMessage = new Message<>(messageHead, contentEncoder);
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
index cf81b1d..2adfd3b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
@@ -38,6 +38,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.hc.core5.http.ConnectionClosedException;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.ContentLengthStrategy;
+import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
@@ -48,7 +49,6 @@ import org.apache.hc.core5.http.config.H1Config;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.message.MessageSupport;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
@@ -73,8 +73,6 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
private final HttpProcessor httpProcessor;
private final ConnectionReuseStrategy connectionReuseStrategy;
private final H1Config h1Config;
- private final ContentLengthStrategy incomingContentStrategy;
- private final ContentLengthStrategy outgoingContentStrategy;
private final Http1StreamListener streamListener;
private final Queue<ClientHttp1StreamHandler> pipeline;
private final Http1StreamChannel<HttpRequest> outputChannel;
@@ -93,15 +91,11 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
final ContentLengthStrategy incomingContentStrategy,
final ContentLengthStrategy outgoingContentStrategy,
final Http1StreamListener streamListener) {
- super(ioSession, h1Config, charCodingConfig, incomingMessageParser, outgoingMessageWriter);
+ super(ioSession, h1Config, charCodingConfig, incomingMessageParser, outgoingMessageWriter, incomingContentStrategy, outgoingContentStrategy);
this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
this.h1Config = h1Config != null ? h1Config : H1Config.DEFAULT;
this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
DefaultConnectionReuseStrategy.INSTANCE;
- this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
- DefaultContentLengthStrategy.INSTANCE;
- this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
- DefaultContentLengthStrategy.INSTANCE;
this.streamListener = streamListener;
this.pipeline = new ConcurrentLinkedQueue<>();
this.outputChannel = new Http1StreamChannel<HttpRequest>() {
@@ -255,11 +249,7 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- protected ContentDecoder handleIncomingMessage(
- final HttpResponse response,
- final ReadableByteChannel channel,
- final SessionInputBuffer buffer,
- final BasicHttpTransportMetrics metrics) throws HttpException {
+ protected boolean handleIncomingMessage(final HttpResponse response) throws HttpException {
if (incoming == null) {
incoming = pipeline.poll();
@@ -267,10 +257,16 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
if (incoming == null) {
throw new HttpException("Unexpected response");
}
- if (!MessageSupport.canResponseHaveBody(incoming.getRequestMethod(), response)) {
- return null;
- }
- final long len = incomingContentStrategy.determineLength(response);
+ return MessageSupport.canResponseHaveBody(incoming.getRequestMethod(), response);
+ }
+
+ @Override
+ protected ContentDecoder createContentDecoder(
+ final long len,
+ final ReadableByteChannel channel,
+ final SessionInputBuffer buffer,
+ final BasicHttpTransportMetrics metrics) throws HttpException {
+
if (len >= 0) {
return new LengthDelimitedDecoder(channel, buffer, metrics, len);
} else if (len == ContentLengthStrategy.CHUNKED) {
@@ -281,12 +277,16 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- protected ContentEncoder handleOutgoingMessage(
- final HttpRequest request,
+ protected boolean handleOutgoingMessage(final HttpRequest request) throws HttpException {
+ return true;
+ }
+
+ @Override
+ protected ContentEncoder createContentEncoder(
+ final long len,
final WritableByteChannel channel,
final SessionOutputBuffer buffer,
final BasicHttpTransportMetrics metrics) throws HttpException {
- final long len = outgoingContentStrategy.determineLength(request);
if (len >= 0) {
return new LengthDelimitedEncoder(channel, buffer, metrics, len, h1Config.getChunkSizeHint());
} else if (len == ContentLengthStrategy.CHUNKED) {
@@ -351,12 +351,12 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- void consumeHeader(final HttpResponse response, final boolean endStream) throws HttpException, IOException {
+ void consumeHeader(final HttpResponse response, final EntityDetails entityDetails) throws HttpException, IOException {
if (streamListener != null) {
streamListener.onResponseHead(this, response);
}
Asserts.notNull(incoming, "Response stream handler");
- incoming.consumeHeader(response, endStream);
+ incoming.consumeHeader(response, entityDetails);
}
@Override
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index fc87b11..a390445 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -44,7 +44,6 @@ import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
import org.apache.hc.core5.http.config.H1Config;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
import org.apache.hc.core5.http.nio.CapacityChannel;
import org.apache.hc.core5.http.nio.DataStreamChannel;
@@ -196,7 +195,7 @@ class ClientHttp1StreamHandler implements ResourceHolder {
}
}
- void consumeHeader(final HttpResponse response, final boolean endStream) throws HttpException, IOException {
+ void consumeHeader(final HttpResponse response, final EntityDetails entityDetails) throws HttpException, IOException {
if (done.get() || responseState != MessageState.HEADERS) {
throw new ProtocolException("Unexpected message head");
}
@@ -237,12 +236,11 @@ class ClientHttp1StreamHandler implements ResourceHolder {
}
}
- final EntityDetails entityDetails = endStream ? null : new LazyEntityDetails(response);
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
httpProcessor.process(response, entityDetails, context);
exchangeHandler.consumeResponse(response, entityDetails);
- if (endStream) {
+ if (entityDetails == null) {
if (!keepAlive) {
outputChannel.close();
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
index 957ccd6..c400cd0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
@@ -38,6 +38,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.hc.core5.http.ConnectionClosedException;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.ContentLengthStrategy;
+import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
@@ -47,7 +48,6 @@ import org.apache.hc.core5.http.config.H1Config;
import org.apache.hc.core5.http.impl.BasicHttpConnectionMetrics;
import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.CapacityChannel;
@@ -74,8 +74,6 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
private final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory;
private final H1Config h1Config;
private final ConnectionReuseStrategy connectionReuseStrategy;
- private final ContentLengthStrategy incomingContentStrategy;
- private final ContentLengthStrategy outgoingContentStrategy;
private final Http1StreamListener streamListener;
private final Queue<ServerHttp1StreamHandler> pipeline;
private final Http1StreamChannel<HttpResponse> outputChannel;
@@ -96,17 +94,13 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
final ContentLengthStrategy incomingContentStrategy,
final ContentLengthStrategy outgoingContentStrategy,
final Http1StreamListener streamListener) {
- super(ioSession, h1Config, charCodingConfig, incomingMessageParser, outgoingMessageWriter);
+ super(ioSession, h1Config, charCodingConfig, incomingMessageParser, outgoingMessageWriter, incomingContentStrategy, outgoingContentStrategy);
this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
this.exchangeHandlerFactory = Args.notNull(exchangeHandlerFactory, "Exchange handler factory");
this.scheme = scheme;
this.h1Config = h1Config != null ? h1Config : H1Config.DEFAULT;
this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
DefaultConnectionReuseStrategy.INSTANCE;
- this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
- DefaultContentLengthStrategy.INSTANCE;
- this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
- DefaultContentLengthStrategy.INSTANCE;
this.streamListener = streamListener;
this.pipeline = new ConcurrentLinkedQueue<>();
this.outputChannel = new Http1StreamChannel<HttpResponse>() {
@@ -255,12 +249,16 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- protected ContentDecoder handleIncomingMessage(
- final HttpRequest request,
+ protected boolean handleIncomingMessage(final HttpRequest request) throws HttpException {
+ return true;
+ }
+
+ @Override
+ protected ContentDecoder createContentDecoder(
+ final long len,
final ReadableByteChannel channel,
final SessionInputBuffer buffer,
final BasicHttpTransportMetrics metrics) throws HttpException {
- final long len = incomingContentStrategy.determineLength(request);
if (len >= 0) {
return new LengthDelimitedDecoder(channel, buffer, metrics, len);
} else if (len == ContentLengthStrategy.CHUNKED) {
@@ -271,12 +269,16 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- protected ContentEncoder handleOutgoingMessage(
- final HttpResponse response,
+ protected boolean handleOutgoingMessage(final HttpResponse response) throws HttpException {
+ return true;
+ }
+
+ @Override
+ protected ContentEncoder createContentEncoder(
+ final long len,
final WritableByteChannel channel,
final SessionOutputBuffer buffer,
final BasicHttpTransportMetrics metrics) throws HttpException {
- final long len = outgoingContentStrategy.determineLength(response);
if (len >= 0) {
return new LengthDelimitedEncoder(channel, buffer, metrics, len, h1Config.getChunkSizeHint());
} else if (len == ContentLengthStrategy.CHUNKED) {
@@ -298,7 +300,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
}
@Override
- void consumeHeader(final HttpRequest request, final boolean endStream) throws HttpException, IOException {
+ void consumeHeader(final HttpRequest request, final EntityDetails entityDetails) throws HttpException, IOException {
if (streamListener != null) {
streamListener.onRequestHead(this, request);
}
@@ -324,7 +326,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
pipeline.add(streamHandler);
}
request.setScheme(scheme);
- streamHandler.consumeHeader(request, endStream);
+ streamHandler.consumeHeader(request, entityDetails);
incoming = streamHandler;
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/c3472dfb/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
index 9c8c6a3..413e8b9 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
@@ -45,7 +45,6 @@ import org.apache.hc.core5.http.NotImplementedException;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
import org.apache.hc.core5.http.nio.AsyncPushProducer;
import org.apache.hc.core5.http.nio.AsyncResponseProducer;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
@@ -228,12 +227,12 @@ class ServerHttp1StreamHandler implements ResourceHolder {
return code;
}
- void consumeHeader(final HttpRequest request, final boolean requestEndStream) throws HttpException, IOException {
+ void consumeHeader(final HttpRequest request, final EntityDetails requestEntityDetails) throws HttpException, IOException {
if (done.get() || requestState != MessageState.HEADERS) {
throw new ProtocolException("Unexpected message head");
}
receivedRequest = request;
- requestState = requestEndStream ? MessageState.COMPLETE : MessageState.BODY;
+ requestState = requestEntityDetails == null ? MessageState.COMPLETE : MessageState.BODY;
AsyncServerExchangeHandler handler;
try {
@@ -256,7 +255,6 @@ class ServerHttp1StreamHandler implements ResourceHolder {
context.setProtocolVersion(transportVersion);
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
- final EntityDetails requestEntityDetails = requestEndStream ? null : new LazyEntityDetails(request);
final ResponseChannel responseChannel = new ResponseChannel() {
@Override