[prev in list] [next in list] [prev in thread] [next in thread]
List: httpcomponents-commits
Subject: [httpcomponents-core] branch master updated: HTTPCORE-616: Make parsing IPv6 ready
From: ckozak () apache ! org
Date: 2021-04-20 12:35:32
Message-ID: 161892213249.10249.13800300441895026398 () gitbox ! apache ! org
[Download RAW message or body]
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
The following commit(s) were added to refs/heads/master by this push:
new 041b4a7 HTTPCORE-616: Make parsing IPv6 ready
041b4a7 is described below
commit 041b4a7f2b6d7beecdce7ac7b1b304d017a3f8d1
Author: Carter Kozak <ckozak@apache.org>
AuthorDate: Mon Apr 5 15:25:23 2021 -0400
HTTPCORE-616: Make parsing IPv6 ready
This adds support for bracketed IPv6 host parsing to the following:
* `org.apache.hc.core5.net.Host.create(String)`
* `org.apache.hc.core5.net.URIAuthority.create(String)`
* `org.apache.hc.core5.http.HttpHost.create(String)`
This commit does not address `InetAddressUtils: Parsing may fail when an
IPv6 scope id might be provided.`
---
.../main/java/org/apache/hc/core5/net/Host.java | 26 ++++++++++++--
.../java/org/apache/hc/core5/net/URISupport.java | 2 ++
.../org/apache/hc/core5/http/TestHttpHost.java | 40 ++++++++++++++++++++++
.../java/org/apache/hc/core5/net/TestHost.java | 33 ++++++++++++++++++
.../org/apache/hc/core5/net/TestURIAuthority.java | 31 +++++++++++++++++
5 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java \
b/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java index d915b0e..2feda01 \
100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/Host.java
@@ -60,7 +60,21 @@ public final class Host implements NamedEndpoint, Serializable {
static Host parse(final CharSequence s, final Tokenizer.Cursor cursor) throws \
URISyntaxException { final Tokenizer tokenizer = Tokenizer.INSTANCE;
- final String hostName = tokenizer.parseContent(s, cursor, \
URISupport.PORT_SEPARATORS); + final String hostName;
+ final boolean ipv6Brackets = !cursor.atEnd() && s.charAt(cursor.getPos()) == \
'['; + if (ipv6Brackets) {
+ cursor.updatePos(cursor.getPos() + 1);
+ hostName = tokenizer.parseContent(s, cursor, \
URISupport.IPV6_HOST_TERMINATORS); + if (cursor.atEnd() || \
!(s.charAt(cursor.getPos()) == ']')) { + throw \
URISupport.createException(s, cursor, "Expected an IPv6 closing bracket ']'"); + \
} + cursor.updatePos(cursor.getPos() + 1);
+ if (!InetAddressUtils.isIPv6Address(hostName)) {
+ throw URISupport.createException(s, cursor, "Expected an IPv6 \
address"); + }
+ } else {
+ hostName = tokenizer.parseContent(s, cursor, \
URISupport.PORT_SEPARATORS); + }
String portText = null;
if (!cursor.atEnd() && s.charAt(cursor.getPos()) == ':') {
cursor.updatePos(cursor.getPos() + 1);
@@ -68,6 +82,9 @@ public final class Host implements NamedEndpoint, Serializable {
}
final int port;
if (!TextUtils.isBlank(portText)) {
+ if (!ipv6Brackets && portText.contains(":")) {
+ throw URISupport.createException(s, cursor, "Expected IPv6 address \
to be enclosed in brackets"); + }
try {
port = Integer.parseInt(portText);
} catch (final NumberFormatException ex) {
@@ -85,7 +102,12 @@ public final class Host implements NamedEndpoint, Serializable {
}
static void format(final StringBuilder buf, final NamedEndpoint endpoint) {
- buf.append(endpoint.getHostName());
+ final String hostName = endpoint.getHostName();
+ if (InetAddressUtils.isIPv6Address(hostName)) {
+ buf.append('[').append(hostName).append(']');
+ } else {
+ buf.append(hostName);
+ }
if (endpoint.getPort() != -1) {
buf.append(":");
buf.append(endpoint.getPort());
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URISupport.java \
b/httpcore5/src/main/java/org/apache/hc/core5/net/URISupport.java index \
6948dc8..e884794 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URISupport.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URISupport.java
@@ -34,6 +34,7 @@ import org.apache.hc.core5.util.Tokenizer;
final class URISupport {
static final BitSet HOST_SEPARATORS = new BitSet(256);
+ static final BitSet IPV6_HOST_TERMINATORS = new BitSet(256);
static final BitSet PORT_SEPARATORS = new BitSet(256);
static final BitSet TERMINATORS = new BitSet(256);
@@ -43,6 +44,7 @@ final class URISupport {
TERMINATORS.set('?');
HOST_SEPARATORS.or(TERMINATORS);
HOST_SEPARATORS.set('@');
+ IPV6_HOST_TERMINATORS.set(']');
PORT_SEPARATORS.or(TERMINATORS);
PORT_SEPARATORS.set(':');
}
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpHost.java \
b/httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpHost.java index \
54019d1..f944f2f 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpHost.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/TestHttpHost.java
@@ -230,4 +230,44 @@ public class TestHttpHost {
}
}
+ @Test
+ public void testIpv6HostAndPort() throws Exception {
+ final HttpHost host = HttpHost.create("[::1]:80");
+ Assert.assertEquals("http", host.getSchemeName());
+ Assert.assertEquals("::1", host.getHostName());
+ Assert.assertEquals(80, host.getPort());
+ }
+
+ @Test
+ public void testIpv6HostAndPortWithScheme() throws Exception {
+ final HttpHost host = HttpHost.create("https://[::1]:80");
+ Assert.assertEquals("https", host.getSchemeName());
+ Assert.assertEquals("::1", host.getHostName());
+ Assert.assertEquals(80, host.getPort());
+ }
+
+ @Test
+ public void testIpv6HostAndPortWithoutBrackets() throws Exception {
+ try {
+ // ambiguous
+ HttpHost.create("::1:80");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ }
+ }
+
+ @Test
+ public void testIpv6HostWithoutPort() throws Exception {
+ try {
+ HttpHost.create("::1");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ }
+ }
+
+ @Test
+ public void testIpv6HostToString() {
+ Assert.assertEquals("http://[::1]:80", new HttpHost("::1", 80).toString());
+ Assert.assertEquals("http://[::1]", new HttpHost("::1", -1).toString());
+ }
}
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/net/TestHost.java \
b/httpcore5/src/test/java/org/apache/hc/core5/net/TestHost.java index \
71f35d5..d03a35a 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/net/TestHost.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/net/TestHost.java
@@ -129,4 +129,37 @@ public class TestHost {
}
}
+ @Test
+ public void testIpv6HostAndPort() throws Exception {
+ final Host host = Host.create("[::1]:80");
+ Assert.assertEquals("::1", host.getHostName());
+ Assert.assertEquals(80, host.getPort());
+ }
+
+ @Test
+ public void testIpv6HostAndPortWithoutBrackets() {
+ try {
+ // ambiguous
+ Host.create("::1:80");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ Assert.assertTrue(expected.getMessage().contains("Expected IPv6 address \
to be enclosed in brackets")); + }
+ }
+
+ @Test
+ public void testIpv6HostWithoutPort() {
+ try {
+ Host.create("::1");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ Assert.assertTrue(expected.getMessage().contains("Expected IPv6 address \
to be enclosed in brackets")); + }
+ }
+
+ @Test
+ public void testIpv6HostToString() {
+ Assert.assertEquals("[::1]:80", new Host("::1", 80).toString());
+ Assert.assertEquals("[::1]", new Host("::1", -1).toString());
+ }
}
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java \
b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java index \
8aa4a22..3fd972c 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIAuthority.java
@@ -220,4 +220,35 @@ public class TestURIAuthority {
}
}
+ @Test
+ public void testCreateFromIPv6String() throws Exception {
+ Assert.assertEquals(new URIAuthority("::1", 8080), \
URIAuthority.create("[::1]:8080")); + Assert.assertEquals(new \
URIAuthority("::1", -1), URIAuthority.create("[::1]")); + try {
+ URIAuthority.create("::1");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ }
+ try {
+ URIAuthority.create("[::1");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ Assert.assertTrue(expected.getMessage().contains("Expected an IPv6 \
closing bracket")); + }
+
+ try {
+ URIAuthority.create("[a]:8080");
+ Assert.fail("URISyntaxException expected");
+ } catch (final URISyntaxException expected) {
+ Assert.assertTrue(expected.getMessage().contains("Expected an IPv6 \
address")); + }
+ }
+
+ @Test
+ public void testIpv6HostToString() {
+ Assert.assertEquals("[::1]:80", new URIAuthority("::1", 80).toString());
+ Assert.assertEquals("user@[::1]:80", new URIAuthority("user", "::1", \
80).toString()); + Assert.assertEquals("[::1]", new URIAuthority("::1", \
-1).toString()); + Assert.assertEquals("user@[::1]", new URIAuthority("user", \
"::1", -1).toString()); + }
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic