You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ck...@apache.org on 2020/09/14 15:16:03 UTC

[httpcomponents-core] 04/13: HTTPCORE-643: Implement NullEntity for convenience (#209)

This is an automated email from the ASF dual-hosted git repository.

ckozak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 1c5b283e4350921fdaf83cda42c917c13bef39a0
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Mon Sep 14 11:13:36 2020 -0400

    HTTPCORE-643: Implement NullEntity for convenience (#209)
---
 .../hc/core5/http/impl/io/BHttpConnectionBase.java |   1 +
 .../hc/core5/http/impl/io/EmptyInputStream.java    |   2 +
 .../hc/core5/http/impl/io/IncomingHttpEntity.java  |   1 +
 .../hc/core5/http/io/entity/BasicHttpEntity.java   |   1 -
 .../{impl/io => io/entity}/EmptyInputStream.java   |   4 +-
 .../entity/NullEntity.java}                        | 104 ++++++++-------------
 .../core5/http/io/entity/TestBasicHttpEntity.java  |   1 -
 .../http/io/entity/TestInputStreamEntity.java      |   1 -
 .../hc/core5/http/io/entity/TestNullEntity.java    |  90 ++++++++++++++++++
 .../http/protocol/TestStandardInterceptors.java    |   2 +-
 10 files changed, 134 insertions(+), 73 deletions(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/BHttpConnectionBase.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/BHttpConnectionBase.java
index 4d8a80c..10683a5 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/BHttpConnectionBase.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/BHttpConnectionBase.java
@@ -58,6 +58,7 @@ import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
 import org.apache.hc.core5.http.io.BHttpConnection;
 import org.apache.hc.core5.http.io.SessionInputBuffer;
 import org.apache.hc.core5.http.io.SessionOutputBuffer;
+import org.apache.hc.core5.http.io.entity.EmptyInputStream;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.io.Closer;
 import org.apache.hc.core5.net.InetAddressUtils;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java
index 8508245..1c3d2e4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java
@@ -31,7 +31,9 @@ import java.io.InputStream;
 
 /**
  * @since 4.4
+ * @deprecated Please use {@link org.apache.hc.core5.http.io.entity.EmptyInputStream}
  */
+@Deprecated
 public final class EmptyInputStream extends InputStream {
 
     public static final EmptyInputStream INSTANCE = new EmptyInputStream();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java
index e831325..ee1228f 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java
@@ -38,6 +38,7 @@ 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.io.entity.AbstractHttpEntity;
+import org.apache.hc.core5.http.io.entity.EmptyInputStream;
 import org.apache.hc.core5.io.Closer;
 
 class IncomingHttpEntity implements HttpEntity {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/BasicHttpEntity.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/BasicHttpEntity.java
index 1d9407e..730ac91 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/BasicHttpEntity.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/BasicHttpEntity.java
@@ -33,7 +33,6 @@ import java.io.InputStream;
 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.http.impl.io.EmptyInputStream;
 import org.apache.hc.core5.io.Closer;
 import org.apache.hc.core5.util.Args;
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EmptyInputStream.java
similarity index 97%
copy from httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java
copy to httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EmptyInputStream.java
index 8508245..294952b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/EmptyInputStream.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/EmptyInputStream.java
@@ -25,12 +25,12 @@
  *
  */
 
-package org.apache.hc.core5.http.impl.io;
+package org.apache.hc.core5.http.io.entity;
 
 import java.io.InputStream;
 
 /**
- * @since 4.4
+ * @since 5.1
  */
 public final class EmptyInputStream extends InputStream {
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/NullEntity.java
similarity index 53%
copy from httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java
copy to httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/NullEntity.java
index e831325..b4b1805 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/IncomingHttpEntity.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/NullEntity.java
@@ -25,7 +25,13 @@
  *
  */
 
-package org.apache.hc.core5.http.impl.io;
+package org.apache.hc.core5.http.io.entity;
+
+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 java.io.IOException;
 import java.io.InputStream;
@@ -34,103 +40,67 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
-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.io.entity.AbstractHttpEntity;
-import org.apache.hc.core5.io.Closer;
-
-class IncomingHttpEntity implements HttpEntity {
-
-    private final InputStream content;
-    private final long len;
-    private final boolean chunked;
-    private final Header contentType;
-    private final Header contentEncoding;
-
-    IncomingHttpEntity(final InputStream content, final long len, final boolean chunked, final Header contentType, final Header contentEncoding) {
-        this.content = content;
-        this.len = len;
-        this.chunked = chunked;
-        this.contentType = contentType;
-        this.contentEncoding = contentEncoding;
-    }
+/**
+ * An empty entity with no content-type. This type may be used for convenience
+ * in place of an empty {@link ByteArrayEntity}.
+ *
+ * @since 5.1
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public final class NullEntity implements HttpEntity {
 
-    @Override
-    public boolean isRepeatable() {
-        return false;
-    }
+    public static final NullEntity INSTANCE = new NullEntity();
+
+    private NullEntity() {}
 
     @Override
-    public boolean isChunked() {
-        return chunked;
+    public boolean isRepeatable() {
+        return true;
     }
 
     @Override
-    public long getContentLength() {
-        return len;
+    public InputStream getContent() throws IOException, UnsupportedOperationException {
+        return EmptyInputStream.INSTANCE;
     }
 
     @Override
-    public String getContentType() {
-        return contentType != null ? contentType.getValue() : null;
-    }
+    public void writeTo(final OutputStream outStream) throws IOException {}
 
     @Override
-    public String getContentEncoding() {
-        return contentEncoding != null ? contentEncoding.getValue() : null;
+    public boolean isStreaming() {
+        return false;
     }
 
     @Override
-    public InputStream getContent() throws IOException, IllegalStateException {
-        return content;
+    public Supplier<List<? extends Header>> getTrailers() {
+        return null;
     }
 
     @Override
-    public boolean isStreaming() {
-        return content != null && content != EmptyInputStream.INSTANCE;
-    }
+    public void close() throws IOException {}
 
     @Override
-    public void writeTo(final OutputStream outStream) throws IOException {
-        AbstractHttpEntity.writeTo(this, outStream);
+    public long getContentLength() {
+        return 0;
     }
 
     @Override
-    public Supplier<List<? extends Header>> getTrailers() {
+    public String getContentType() {
         return null;
     }
 
     @Override
-    public Set<String> getTrailerNames() {
-        return Collections.emptySet();
+    public String getContentEncoding() {
+        return null;
     }
 
     @Override
-    public void close() throws IOException {
-        Closer.close(content);
+    public boolean isChunked() {
+        return false;
     }
 
     @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        sb.append("Content-Type: ");
-        sb.append(getContentType());
-        sb.append(',');
-        sb.append("Content-Encoding: ");
-        sb.append(getContentEncoding());
-        sb.append(',');
-        final long len = getContentLength();
-        if (len >= 0) {
-            sb.append("Content-Length: ");
-            sb.append(len);
-            sb.append(',');
-        }
-        sb.append("Chunked: ");
-        sb.append(isChunked());
-        sb.append(']');
-        return sb.toString();
+    public Set<String> getTrailerNames() {
+        return Collections.emptySet();
     }
-
 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestBasicHttpEntity.java b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestBasicHttpEntity.java
index b2ac16e..8012585 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestBasicHttpEntity.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestBasicHttpEntity.java
@@ -32,7 +32,6 @@ import java.io.ByteArrayOutputStream;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.impl.io.EmptyInputStream;
 import org.junit.Assert;
 import org.junit.Test;
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestInputStreamEntity.java b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestInputStreamEntity.java
index 04f937b..35e0e17 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestInputStreamEntity.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestInputStreamEntity.java
@@ -33,7 +33,6 @@ import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.impl.io.EmptyInputStream;
 import org.junit.Assert;
 import org.junit.Test;
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestNullEntity.java b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestNullEntity.java
new file mode 100644
index 0000000..c2abce3
--- /dev/null
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestNullEntity.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.io.entity;
+
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+public class TestNullEntity {
+
+    @Test
+    public void testLength() {
+        assertEquals(0, NullEntity.INSTANCE.getContentLength());
+    }
+
+    @Test
+    public void testContentType() {
+        assertNull(NullEntity.INSTANCE.getContentType());
+    }
+
+    @Test
+    public void testContentEncoding() {
+        assertNull(NullEntity.INSTANCE.getContentEncoding());
+    }
+
+    @Test
+    public void testTrailerNames() {
+        assertEquals(Collections.emptySet(), NullEntity.INSTANCE.getTrailerNames());
+    }
+
+    @Test
+    public void testContentStream() throws IOException {
+        try (InputStream content = NullEntity.INSTANCE.getContent()) {
+            assertEquals(-1, content.read());
+        }
+        // Closing the resource should have no impact
+        try (InputStream content = NullEntity.INSTANCE.getContent()) {
+            assertEquals(-1, content.read());
+        }
+    }
+
+    @Test
+    public void testWriteTo() throws IOException {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        NullEntity.INSTANCE.writeTo(baos);
+        assertEquals(0, baos.size());
+    }
+
+    @Test
+    public void testIsStreaming() {
+        assertFalse(NullEntity.INSTANCE.isStreaming());
+    }
+
+    @Test
+    public void testIsChunked() {
+        assertFalse(NullEntity.INSTANCE.isChunked());
+    }
+}
\ No newline at end of file
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 8ed0f1e..cef1f8a 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
@@ -38,7 +38,7 @@ import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.ProtocolException;
-import org.apache.hc.core5.http.impl.io.EmptyInputStream;
+import org.apache.hc.core5.http.io.entity.EmptyInputStream;
 import org.apache.hc.core5.http.io.entity.BasicHttpEntity;
 import org.apache.hc.core5.http.io.entity.HttpEntities;
 import org.apache.hc.core5.http.io.entity.StringEntity;