1616
1717package com .rabbitmq .client ;
1818
19+ import org .slf4j .Logger ;
20+ import org .slf4j .LoggerFactory ;
21+
1922/**
2023 * A representation of network addresses, i.e. host/port pairs,
2124 * with some utility functions for parsing address strings.
2225*/
2326public class Address {
24- /** host name **/
27+ private static final Logger LOGGER = LoggerFactory .getLogger (Address .class );
28+
29+ /**
30+ * host name
31+ **/
2532 private final String _host ;
26- /** port number **/
33+ /**
34+ * port number
35+ **/
2736 private final int _port ;
2837
2938 /**
3039 * Construct an address from a host name and port number.
40+ *
3141 * @param host the host name
3242 * @param port the port number
3343 */
@@ -38,6 +48,7 @@ public Address(String host, int port) {
3848
3949 /**
4050 * Construct an address from a host.
51+ *
4152 * @param host the host name
4253 */
4354 public Address (String host ) {
@@ -47,6 +58,7 @@ public Address(String host) {
4758
4859 /**
4960 * Get the host name
61+ *
5062 * @return the host name
5163 */
5264 public String getHost () {
@@ -55,23 +67,98 @@ public String getHost() {
5567
5668 /**
5769 * Get the port number
70+ *
5871 * @return the port number
5972 */
6073 public int getPort () {
6174 return _port ;
6275 }
6376
77+ /**
78+ * Extracts hostname or IP address from a string containing a hostname, IP address,
79+ * hostname:port pair or IP address:port pair.
80+ * Note that IPv6 addresses must be quoted with square brackets, e.g. [2001:db8:85a3:8d3:1319:8a2e:370:7348].
81+ *
82+ * @param addressString the string to extract hostname from
83+ * @return the hostname or IP address
84+ */
85+ public static String parseHost (String addressString ) {
86+ // we need to handle cases such as [2001:db8:85a3:8d3:1319:8a2e:370:7348]:5671
87+ int lastColon = addressString .lastIndexOf (":" );
88+ int lastClosingSquareBracket = addressString .lastIndexOf ("]" );
89+ if (lastClosingSquareBracket == -1 ) {
90+ String [] parts = addressString .split (":" );
91+ if (parts .length > 2 ) {
92+ String msg = "Address " +
93+ addressString +
94+ " seems to contain an unquoted IPv6 address. Make sure you quote IPv6 addresses like so: [2001:db8:85a3:8d3:1319:8a2e:370:7348]" ;
95+ LOGGER .error (msg );
96+ throw new IllegalArgumentException (msg );
97+ }
98+
99+ return parts [0 ];
100+ }
101+
102+ if (lastClosingSquareBracket < lastColon ) {
103+ // there is a port
104+ return addressString .substring (0 , lastColon );
105+ } else {
106+ return addressString ;
107+ }
108+ }
109+
110+ public static int parsePort (String addressString ) {
111+ // we need to handle cases such as [2001:db8:85a3:8d3:1319:8a2e:370:7348]:5671
112+ int lastColon = addressString .lastIndexOf (":" );
113+ int lastClosingSquareBracket = addressString .lastIndexOf ("]" );
114+ if (lastClosingSquareBracket == -1 ) {
115+ String [] parts = addressString .split (":" );
116+ if (parts .length > 2 ) {
117+ String msg = "Address " +
118+ addressString +
119+ " seems to contain an unquoted IPv6 address. Make sure you quote IPv6 addresses like so: [2001:db8:85a3:8d3:1319:8a2e:370:7348]" ;
120+ LOGGER .error (msg );
121+ throw new IllegalArgumentException (msg );
122+ }
123+
124+ if (parts .length == 2 ) {
125+ return Integer .parseInt (parts [1 ]);
126+ }
127+
128+ return ConnectionFactory .USE_DEFAULT_PORT ;
129+ }
130+
131+ if (lastClosingSquareBracket < lastColon ) {
132+ // there is a port
133+ return Integer .parseInt (addressString .substring (lastColon + 1 ));
134+ }
135+
136+ return ConnectionFactory .USE_DEFAULT_PORT ;
137+ }
138+
139+ public static boolean isHostWithPort (String addressString ) {
140+ // we need to handle cases such as [2001:db8:85a3:8d3:1319:8a2e:370:7348]:5671
141+ int lastColon = addressString .lastIndexOf (":" );
142+ int lastClosingSquareBracket = addressString .lastIndexOf ("]" );
143+
144+ if (lastClosingSquareBracket == -1 ) {
145+ return addressString .contains (":" );
146+ } else {
147+ return lastClosingSquareBracket < lastColon ;
148+ }
149+ }
150+
64151 /**
65152 * Factory method: takes a formatted addressString string as construction parameter
66153 * @param addressString an addressString of the form "host[:port]".
67154 * @return an {@link Address} from the given data
68155 */
69156 public static Address parseAddress (String addressString ) {
70- int idx = addressString . indexOf ( ':' );
71- return ( idx == - 1 ) ?
72- new Address ( addressString ) :
73- new Address (addressString . substring ( 0 , idx ),
74- Integer . parseInt ( addressString . substring ( idx + 1 )));
157+ if ( isHostWithPort ( addressString )) {
158+ return new Address ( parseHost ( addressString ), parsePort ( addressString ));
159+ } else {
160+ return new Address (addressString );
161+ }
75162 }
76163
77164 /**
0 commit comments