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");
+ }
+
}