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 2020/11/24 19:13:03 UTC

[httpcomponents-client] 01/08: Fix NPE when H2/Async client interceptors are added using first/last (#268)

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

olegk pushed a commit to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git

commit e85aab4c89b8b1d4ed0977f884a0c0257ae270eb
Author: Koji Lin <ko...@gmail.com>
AuthorDate: Fri Nov 6 17:49:55 2020 +0900

    Fix NPE when H2/Async client interceptors are added using first/last (#268)
---
 .../http/impl/async/H2AsyncClientBuilder.java      |  6 ++
 .../http/impl/async/HttpAsyncClientBuilder.java    |  6 ++
 .../impl/classic/TestHttpAsyncClientBuilder.java   | 85 ++++++++++++++++++++++
 3 files changed, 97 insertions(+)

diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
index c364677..41c6e5f 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
@@ -338,6 +338,9 @@ public class H2AsyncClientBuilder {
     public final H2AsyncClientBuilder addExecInterceptorFirst(final String name, final AsyncExecChainHandler interceptor) {
         Args.notNull(name, "Name");
         Args.notNull(interceptor, "Interceptor");
+        if (execInterceptors == null) {
+            execInterceptors = new LinkedList<>();
+        }
         execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.FIRST, name, interceptor, null));
         return this;
     }
@@ -348,6 +351,9 @@ public class H2AsyncClientBuilder {
     public final H2AsyncClientBuilder addExecInterceptorLast(final String name, final AsyncExecChainHandler interceptor) {
         Args.notNull(name, "Name");
         Args.notNull(interceptor, "Interceptor");
+        if (execInterceptors == null) {
+            execInterceptors = new LinkedList<>();
+        }
         execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.LAST, name, interceptor, null));
         return this;
     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
index 5fa828e..adb341d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
@@ -445,6 +445,9 @@ public class HttpAsyncClientBuilder {
     public final HttpAsyncClientBuilder addExecInterceptorFirst(final String name, final AsyncExecChainHandler interceptor) {
         Args.notNull(name, "Name");
         Args.notNull(interceptor, "Interceptor");
+        if (execInterceptors == null) {
+            execInterceptors = new LinkedList<>();
+        }
         execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.FIRST, name, interceptor, null));
         return this;
     }
@@ -455,6 +458,9 @@ public class HttpAsyncClientBuilder {
     public final HttpAsyncClientBuilder addExecInterceptorLast(final String name, final AsyncExecChainHandler interceptor) {
         Args.notNull(name, "Name");
         Args.notNull(interceptor, "Interceptor");
+        if (execInterceptors == null) {
+            execInterceptors = new LinkedList<>();
+        }
         execInterceptors.add(new ExecInterceptorEntry(ExecInterceptorEntry.Postion.LAST, name, interceptor, null));
         return this;
     }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpAsyncClientBuilder.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpAsyncClientBuilder.java
new file mode 100644
index 0000000..ea6e802
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpAsyncClientBuilder.java
@@ -0,0 +1,85 @@
+/*
+ * ====================================================================
+ * 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.client5.http.impl.classic;
+
+import java.io.IOException;
+
+import org.apache.hc.client5.http.async.AsyncExecCallback;
+import org.apache.hc.client5.http.async.AsyncExecChain;
+import org.apache.hc.client5.http.async.AsyncExecChainHandler;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.junit.Test;
+
+public class TestHttpAsyncClientBuilder {
+
+    @Test
+    public void testAddInterceptorFirstDoesNotThrow() throws IOException {
+        HttpAsyncClients.custom()
+                .addExecInterceptorFirst("first", NopExecChainHandler.INSTANCE)
+                .build()
+                .close();
+    }
+
+    @Test
+    public void testAddInterceptorLastDoesNotThrow() throws IOException {
+        HttpAsyncClients.custom()
+                .addExecInterceptorLast("last", NopExecChainHandler.INSTANCE)
+                .build()
+                .close();
+    }
+
+    @Test
+    public void testH2AddInterceptorFirstDoesNotThrow() throws IOException {
+        HttpAsyncClients.customHttp2()
+                .addExecInterceptorFirst("first", NopExecChainHandler.INSTANCE)
+                .build()
+                .close();
+    }
+
+    @Test
+    public void testH2AddInterceptorLastDoesNotThrow() throws IOException {
+        HttpAsyncClients.customHttp2()
+                .addExecInterceptorLast("last", NopExecChainHandler.INSTANCE)
+                .build()
+                .close();
+    }
+
+    enum NopExecChainHandler implements AsyncExecChainHandler {
+        INSTANCE;
+
+        @Override
+        public void execute(final HttpRequest request, final AsyncEntityProducer entityProducer,
+                            final AsyncExecChain.Scope scope, final AsyncExecChain chain,
+                            final AsyncExecCallback asyncExecCallback)
+                throws HttpException, IOException {
+            chain.proceed(request, entityProducer, scope, asyncExecCallback);
+        }
+    }
+}