1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.core5.net;
28
29 import java.io.Serializable;
30 import java.net.URISyntaxException;
31 import java.util.Locale;
32
33 import org.apache.hc.core5.annotation.Contract;
34 import org.apache.hc.core5.annotation.ThreadingBehavior;
35 import org.apache.hc.core5.util.Args;
36 import org.apache.hc.core5.util.LangUtils;
37 import org.apache.hc.core5.util.TextUtils;
38 import org.apache.hc.core5.util.Tokenizer;
39
40
41
42
43
44
45
46 @Contract(threading = ThreadingBehavior.IMMUTABLE)
47 public final class Host implements NamedEndpoint, Serializable {
48
49 private static final long serialVersionUID = 1L;
50 private final String name;
51 private final String lcName;
52 private final int port;
53
54 public Host(final String name, final int port) {
55 super();
56 this.name = Args.notNull(name, "Host name");
57 this.port = Ports.checkWithDefault(port);
58 this.lcName = this.name.toLowerCase(Locale.ROOT);
59 }
60
61 static Host parse(final CharSequence s, final Tokenizer.Cursor cursor) throws URISyntaxException {
62 final Tokenizer tokenizer = Tokenizer.INSTANCE;
63 final String hostName;
64 final boolean ipv6Brackets = !cursor.atEnd() && s.charAt(cursor.getPos()) == '[';
65 if (ipv6Brackets) {
66 cursor.updatePos(cursor.getPos() + 1);
67 hostName = tokenizer.parseContent(s, cursor, URISupport.IPV6_HOST_TERMINATORS);
68 if (cursor.atEnd() || !(s.charAt(cursor.getPos()) == ']')) {
69 throw URISupport.createException(s, cursor, "Expected an IPv6 closing bracket ']'");
70 }
71 cursor.updatePos(cursor.getPos() + 1);
72 if (!InetAddressUtils.isIPv6Address(hostName)) {
73 throw URISupport.createException(s, cursor, "Expected an IPv6 address");
74 }
75 } else {
76 hostName = tokenizer.parseContent(s, cursor, URISupport.PORT_SEPARATORS);
77 }
78 String portText = null;
79 if (!cursor.atEnd() && s.charAt(cursor.getPos()) == ':') {
80 cursor.updatePos(cursor.getPos() + 1);
81 portText = tokenizer.parseContent(s, cursor, URISupport.TERMINATORS);
82 }
83 final int port;
84 if (!TextUtils.isBlank(portText)) {
85 if (!ipv6Brackets && portText.contains(":")) {
86 throw URISupport.createException(s, cursor, "Expected IPv6 address to be enclosed in brackets");
87 }
88 try {
89 port = Integer.parseInt(portText);
90 } catch (final NumberFormatException ex) {
91 throw URISupport.createException(s, cursor, "Port is invalid");
92 }
93 } else {
94 port = -1;
95 }
96 return new Host(hostName, port);
97 }
98
99 static Host parse(final CharSequence s) throws URISyntaxException {
100 final Tokenizer.Cursor cursor = new Tokenizer.Cursor(0, s.length());
101 return parse(s, cursor);
102 }
103
104 static void format(final StringBuilder buf, final NamedEndpoint endpoint) {
105 final String hostName = endpoint.getHostName();
106 if (InetAddressUtils.isIPv6Address(hostName)) {
107 buf.append('[').append(hostName).append(']');
108 } else {
109 buf.append(hostName);
110 }
111 if (endpoint.getPort() != -1) {
112 buf.append(":");
113 buf.append(endpoint.getPort());
114 }
115 }
116
117 static void format(final StringBuilder buf, final Host host) {
118 format(buf, (NamedEndpoint) host);
119 }
120
121 static String format(final Host host) {
122 final StringBuilder buf = new StringBuilder();
123 format(buf, host);
124 return buf.toString();
125 }
126
127 public static Host create(final String s) throws URISyntaxException {
128 Args.notEmpty(s, "HTTP Host");
129 final Tokenizer.Cursor cursor = new Tokenizer.Cursor(0, s.length());
130 final Host host = parse(s, cursor);
131 if (TextUtils.isBlank(host.getHostName())) {
132 throw URISupport.createException(s, cursor, "Hostname is invalid");
133 }
134 if (!cursor.atEnd()) {
135 throw URISupport.createException(s, cursor, "Unexpected content");
136 }
137 return host;
138 }
139
140 @Override
141 public String getHostName() {
142 return name;
143 }
144
145 @Override
146 public int getPort() {
147 return port;
148 }
149
150 @Override
151 public boolean equals(final Object o) {
152 if (this == o) {
153 return true;
154 }
155 if (o instanceof Host) {
156 final Hostef="../../../../../org/apache/hc/core5/net/Host.html#Host">Host that = (Host) o;
157 return this.lcName.equals(that.lcName) && this.port == that.port;
158 }
159 return false;
160 }
161
162 @Override
163 public int hashCode() {
164 int hash = LangUtils.HASH_SEED;
165 hash = LangUtils.hashCode(hash, this.lcName);
166 hash = LangUtils.hashCode(hash, this.port);
167 return hash;
168 }
169
170 @Override
171 public String toString() {
172 return format(this);
173 }
174
175 }