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 2021/02/28 10:55:09 UTC

[httpcomponents-core] branch master updated: * Improve and clean validation class * Re use IPV4 and IPV6 constant

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5b1207b  * Improve and clean validation class * Re use IPV4 and IPV6 constant
5b1207b is described below

commit 5b1207b29c5e37d509ac9c7772cd56b3646c5a5d
Author: Arturo Bernal <ar...@gmail.com>
AuthorDate: Sun Feb 28 08:54:22 2021 +0100

    * Improve and clean validation class
    * Re use IPV4 and IPV6 constant
---
 .../org/apache/hc/core5/testing/SocksProxy.java    |  11 +--
 .../org/apache/hc/core5/net/InetAddressUtils.java  |  13 +++
 .../core5/reactor/SocksProxyProtocolHandler.java   |  12 +--
 .../main/java/org/apache/hc/core5/util/Args.java   | 103 ++++++++++++++-------
 .../java/org/apache/hc/core5/util/TestArgs.java    |  48 ++++++++++
 5 files changed, 141 insertions(+), 46 deletions(-)

diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
index ee3c111..3a200d3 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
@@ -38,6 +38,7 @@ import java.net.SocketAddress;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.hc.core5.net.InetAddressUtils;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
@@ -49,9 +50,7 @@ public class SocksProxy {
 
         public static final int VERSION_5 = 5;
         public static final int COMMAND_CONNECT = 1;
-        public static final int ATYP_IPV4 = 1;
         public static final int ATYP_DOMAINNAME = 3;
-        public static final int ATYP_IPV6 = 4;
 
         private final SocksProxy parent;
         private final Socket socket;
@@ -113,14 +112,14 @@ public class SocksProxy {
                     final byte[] targetAddress;
                     final int addressType = input.readUnsignedByte();
                     switch (addressType) {
-                        case ATYP_IPV4:
+                        case InetAddressUtils.IPV4:
                             targetHost = null;
                             targetAddress = new byte[4];
                             for (int i = 0; i < targetAddress.length; i++) {
                                 targetAddress[i] = input.readByte();
                             }
                             break;
-                        case ATYP_IPV6:
+                        case InetAddressUtils.IPV6:
                             targetHost = null;
                             targetAddress = new byte[16];
                             for (int i = 0; i < targetAddress.length; i++) {
@@ -153,9 +152,9 @@ public class SocksProxy {
                     output.writeByte(0); /* reserved */
                     final byte[] localAddress = target.getLocalAddress().getAddress();
                     if (localAddress.length == 4) {
-                        output.writeByte(ATYP_IPV4);
+                        output.writeByte(InetAddressUtils.IPV4);
                     } else if (localAddress.length == 16) {
-                        output.writeByte(ATYP_IPV6);
+                        output.writeByte(InetAddressUtils.IPV6);
                     } else {
                         throw new IOException("Unsupported localAddress byte length: " + localAddress.length);
                     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/InetAddressUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/net/InetAddressUtils.java
index 81c7cde..cf5e9f2 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/InetAddressUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/InetAddressUtils.java
@@ -42,6 +42,19 @@ import org.apache.hc.core5.util.Args;
  */
 public class InetAddressUtils {
 
+    /**
+     * Represents the ipv4
+     *
+     * @since 5.1
+     */
+    public static final byte IPV4 = 1;
+    /**
+     * Represents the ipv6.
+     *
+     * @since 5.1
+     */
+    public static final byte IPV6 = 4;
+
     private InetAddressUtils() {
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
index 9d3e72e..a66ca7c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SocksProxyProtocolHandler.java
@@ -42,6 +42,7 @@ import java.nio.charset.StandardCharsets;
 import org.apache.hc.core5.http.nio.command.CommandSupport;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.io.SocketTimeoutExceptionFactory;
+import org.apache.hc.core5.net.InetAddressUtils;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -64,11 +65,8 @@ final class SocksProxyProtocolHandler implements IOEventHandler {
 
     private static final byte COMMAND_CONNECT = 1;
 
-    private static final byte ATYP_IPV4 = 1;
-
     private static final byte ATYP_DOMAINNAME = 3;
 
-    private static final byte ATYP_IPV6 = 4;
 
     private enum State {
         SEND_AUTH, RECEIVE_AUTH_METHOD, SEND_USERNAME_PASSWORD, RECEIVE_AUTH, SEND_CONNECT, RECEIVE_RESPONSE_CODE, RECEIVE_ADDRESS_TYPE, RECEIVE_ADDRESS, COMPLETE
@@ -212,9 +210,9 @@ final class SocksProxyProtocolHandler implements IOEventHandler {
                     this.buffer.get(); // reserved byte that has no purpose
                     final byte aType = this.buffer.get();
                     final int addressSize;
-                    if (aType == ATYP_IPV4) {
+                    if (aType == InetAddressUtils.IPV4) {
                         addressSize = 4;
-                    } else if (aType == ATYP_IPV6) {
+                    } else if (aType == InetAddressUtils.IPV6) {
                         addressSize = 16;
                     } else if (aType == ATYP_DOMAINNAME) {
                         // mask with 0xFF to convert to unsigned byte value
@@ -263,10 +261,10 @@ final class SocksProxyProtocolHandler implements IOEventHandler {
         this.buffer.put(COMMAND_CONNECT);
         this.buffer.put((byte) 0); // reserved
         if (address instanceof Inet4Address) {
-            this.buffer.put(ATYP_IPV4);
+            this.buffer.put(InetAddressUtils.IPV4);
             this.buffer.put(address.getAddress());
         } else if (address instanceof Inet6Address) {
-            this.buffer.put(ATYP_IPV6);
+            this.buffer.put(InetAddressUtils.IPV6);
             this.buffer.put(address.getAddress());
         } else {
             throw new IOException("Unsupported remote address class: " + address.getClass().getName());
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/util/Args.java b/httpcore5/src/main/java/org/apache/hc/core5/util/Args.java
index 25bc011..6ff4911 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/util/Args.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/util/Args.java
@@ -27,7 +27,10 @@
 
 package org.apache.hc.core5.util;
 
+import java.lang.reflect.Array;
 import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
 
 import org.apache.hc.core5.http.EntityDetails;
 
@@ -45,12 +48,6 @@ public class Args {
         }
     }
 
-    public static void check(final boolean expression, final String message, final Object arg) {
-        if (!expression) {
-            throw new IllegalArgumentException(String.format(message, arg));
-        }
-    }
-
     public static long checkContentLength(final EntityDetails entityDetails) {
         // -1 is a special value,
         // 0 is allowed as well,
@@ -78,10 +75,8 @@ public class Args {
     }
 
     public static <T extends CharSequence> T containsNoBlanks(final T argument, final String name) {
-        if (argument == null) {
-            throw NullPointerException(name);
-        }
-        if (argument.length() == 0) {
+        notNull(argument, name);
+        if (isEmpty(argument)) {
             throw illegalArgumentExceptionNotEmpty(name);
         }
         if (TextUtils.containsBlanks(argument)) {
@@ -103,30 +98,16 @@ public class Args {
     }
 
     public static <T extends CharSequence> T notBlank(final T argument, final String name) {
-        if (argument == null) {
-            throw NullPointerException(name);
-        }
+        notNull(argument, name);
         if (TextUtils.isBlank(argument)) {
             throw new IllegalArgumentException(name + " must not be blank");
         }
         return argument;
     }
 
-    public static <T extends CharSequence> T notEmpty(final T argument, final String name) {
-        if (argument == null) {
-            throw NullPointerException(name);
-        }
-        if (TextUtils.isEmpty(argument)) {
-            throw illegalArgumentExceptionNotEmpty(name);
-        }
-        return argument;
-    }
-
-    public static <E, T extends Collection<E>> T notEmpty(final T argument, final String name) {
-        if (argument == null) {
-            throw NullPointerException(name);
-        }
-        if (argument.isEmpty()) {
+    public static <T> T notEmpty(final T argument, final String name) {
+        notNull(argument, name);
+        if (isEmpty(argument)) {
             throw illegalArgumentExceptionNotEmpty(name);
         }
         return argument;
@@ -146,11 +127,64 @@ public class Args {
         return n;
     }
 
+    /**
+     * <p>Validate that the specified argument is not {@code null};
+     * otherwise throwing an exception with the specified message.
+     *
+     * <pre>Args.notNull(myObject, "The object must not be null");</pre>
+     *
+     * @param <T> the object type
+     * @param argument  the object to check
+     * @param name  the {@link String} exception message if invalid, not null
+     * @return the validated object (never {@code null} for method chaining)
+     * @throws NullPointerException if the object is {@code null}
+     */
     public static <T> T notNull(final T argument, final String name) {
-        if (argument == null) {
-            throw NullPointerException(name);
-        }
-        return argument;
+        return Objects.requireNonNull(argument, name);
+    }
+
+    /**
+     * <p>Checks if an Object is empty or null.</p>
+     *
+     * The following types are supported:
+     * <ul>
+     * <li>{@link CharSequence}: Considered empty if its length is zero.</li>
+     * <li>{@code Array}: Considered empty if its length is zero.</li>
+     * <li>{@link Collection}: Considered empty if it has zero elements.</li>
+     * <li>{@link Map}: Considered empty if it has zero key-value mappings.</li>
+     * </ul>
+     *
+     * <pre>
+     * Args.isEmpty(null)             = true
+     * Args.isEmpty("")               = true
+     * Args.isEmpty("ab")             = false
+     * Args.isEmpty(new int[]{})      = true
+     * Args.isEmpty(new int[]{1,2,3}) = false
+     * Args.isEmpty(1234)             = false
+     * </pre>
+     *
+     * @param object  the {@code Object} to test, may be {@code null}
+     * @return {@code true} if the object has a supported type and is empty or null,
+     * {@code false} otherwise
+     * @since 5.1
+     */
+    public static boolean isEmpty(final Object object) {
+        if (object == null) {
+            return true;
+        }
+        if (object instanceof CharSequence) {
+            return ((CharSequence) object).length() == 0;
+        }
+        if (object.getClass().isArray()) {
+            return Array.getLength(object) == 0;
+        }
+        if (object instanceof Collection<?>) {
+            return ((Collection<?>) object).isEmpty();
+        }
+        if (object instanceof Map<?, ?>) {
+            return ((Map<?, ?>) object).isEmpty();
+        }
+        return false;
     }
 
     public static int positive(final int n, final String name) {
@@ -172,8 +206,11 @@ public class Args {
         return timeValue;
     }
 
+    /**
+     * Private constructor so that no instances can be created. This class
+     * contains only static utility methods.
+     */
     private Args() {
-        // Do not allow utility class to be instantiated.
     }
 
 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java b/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
index f82a8c9..f21635f 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
@@ -27,9 +27,14 @@
 
 package org.apache.hc.core5.util;
 
+import java.text.ParseException;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -127,6 +132,11 @@ public class TestArgs {
         Assert.assertEquals(1L, Args.positive(1L, "Number"));
     }
 
+    @Test
+    public void testPositiveTimeValuePass() throws ParseException {
+        final Timeout timeout = Timeout.parse("1200 MILLISECONDS");
+        Assert.assertEquals(timeout, Args.positive(timeout, "No Error"));
+    }
     @Test(expected=IllegalArgumentException.class)
     public void testPositiveLongFail1() {
         Args.positive(-1L, "Number");
@@ -225,4 +235,42 @@ public class TestArgs {
         Args.checkRange(0L, Long.MIN_VALUE, Long.MAX_VALUE, "Number");
     }
 
+    @Test
+    public void testIsEmpty() {
+
+        final String[] NON_EMPTY_ARRAY = new String[] { "ABG", "NML", };
+
+        final List<String> NON_EMPTY_LIST = Arrays.asList(NON_EMPTY_ARRAY);
+
+        final Set<String> NON_EMPTY_SET = new HashSet<>(NON_EMPTY_LIST);
+
+        final Map<String, String> NON_EMPTY_MAP = new HashMap<>();
+        NON_EMPTY_MAP.put("ABG", "MNL");
+
+        Assert.assertTrue(Args.isEmpty(null));
+        Assert.assertTrue(Args.isEmpty(""));
+        Assert.assertTrue(Args.isEmpty(new int[] {}));
+        Assert.assertTrue(Args.isEmpty(Collections.emptyList()));
+        Assert.assertTrue(Args.isEmpty(Collections.emptySet()));
+        Assert.assertTrue(Args.isEmpty(Collections.emptyMap()));
+
+        Assert.assertFalse(Args.isEmpty("  "));
+        Assert.assertFalse(Args.isEmpty("ab"));
+        Assert.assertFalse(Args.isEmpty(NON_EMPTY_ARRAY));
+        Assert.assertFalse(Args.isEmpty(NON_EMPTY_LIST));
+        Assert.assertFalse(Args.isEmpty(NON_EMPTY_SET));
+        Assert.assertFalse(Args.isEmpty(NON_EMPTY_MAP));
+    }
+
+    @Test
+    public void testcontainsNoBlanks() {
+        final String stuff = "abg";
+        Assert.assertSame(stuff, Args.containsNoBlanks(stuff, "abg"));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void check() {
+        Args.check(false, "Error,", "ABG");
+    }
+
 }