blob: c9bca2876b0a23072e413167779f341098bb11b5 [file] [log] [blame]
Remi NGUYEN VANfbbccbc2021-01-15 18:08:24 +09001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.compat.annotation.UnsupportedAppUsage;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.text.TextUtils;
25
26import java.net.InetSocketAddress;
27import java.net.URLConnection;
28import java.util.List;
29import java.util.Locale;
30
31/**
32 * Describes a proxy configuration.
33 *
34 * Proxy configurations are already integrated within the {@code java.net} and
35 * Apache HTTP stack. So {@link URLConnection} and Apache's {@code HttpClient} will use
36 * them automatically.
37 *
38 * Other HTTP stacks will need to obtain the proxy info from
39 * {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}.
40 */
41public class ProxyInfo implements Parcelable {
42
43 private final String mHost;
44 private final int mPort;
45 private final String mExclusionList;
46 private final String[] mParsedExclusionList;
47 private final Uri mPacFileUrl;
48
49 /**
50 *@hide
51 */
52 public static final String LOCAL_EXCL_LIST = "";
53 /**
54 *@hide
55 */
56 public static final int LOCAL_PORT = -1;
57 /**
58 *@hide
59 */
60 public static final String LOCAL_HOST = "localhost";
61
62 /**
63 * Constructs a {@link ProxyInfo} object that points at a Direct proxy
64 * on the specified host and port.
65 */
66 public static ProxyInfo buildDirectProxy(String host, int port) {
67 return new ProxyInfo(host, port, null);
68 }
69
70 /**
71 * Constructs a {@link ProxyInfo} object that points at a Direct proxy
72 * on the specified host and port.
73 *
74 * The proxy will not be used to access any host in exclusion list, exclList.
75 *
76 * @param exclList Hosts to exclude using the proxy on connections for. These
77 * hosts can use wildcards such as *.example.com.
78 */
79 public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) {
80 String[] array = exclList.toArray(new String[exclList.size()]);
81 return new ProxyInfo(host, port, TextUtils.join(",", array), array);
82 }
83
84 /**
85 * Construct a {@link ProxyInfo} that will download and run the PAC script
86 * at the specified URL.
87 */
88 public static ProxyInfo buildPacProxy(Uri pacUri) {
89 return new ProxyInfo(pacUri);
90 }
91
92 /**
93 * Construct a {@link ProxyInfo} object that will download and run the PAC script at the
94 * specified URL and port.
95 */
96 @NonNull
97 public static ProxyInfo buildPacProxy(@NonNull Uri pacUrl, int port) {
98 return new ProxyInfo(pacUrl, port);
99 }
100
101 /**
102 * Create a ProxyProperties that points at a HTTP Proxy.
103 * @hide
104 */
105 @UnsupportedAppUsage
106 public ProxyInfo(String host, int port, String exclList) {
107 mHost = host;
108 mPort = port;
109 mExclusionList = exclList;
110 mParsedExclusionList = parseExclusionList(mExclusionList);
111 mPacFileUrl = Uri.EMPTY;
112 }
113
114 /**
115 * Create a ProxyProperties that points at a PAC URL.
116 * @hide
117 */
118 public ProxyInfo(@NonNull Uri pacFileUrl) {
119 mHost = LOCAL_HOST;
120 mPort = LOCAL_PORT;
121 mExclusionList = LOCAL_EXCL_LIST;
122 mParsedExclusionList = parseExclusionList(mExclusionList);
123 if (pacFileUrl == null) {
124 throw new NullPointerException();
125 }
126 mPacFileUrl = pacFileUrl;
127 }
128
129 /**
130 * Only used in PacProxyInstaller after Local Proxy is bound.
131 * @hide
132 */
133 public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) {
134 mHost = LOCAL_HOST;
135 mPort = localProxyPort;
136 mExclusionList = LOCAL_EXCL_LIST;
137 mParsedExclusionList = parseExclusionList(mExclusionList);
138 if (pacFileUrl == null) {
139 throw new NullPointerException();
140 }
141 mPacFileUrl = pacFileUrl;
142 }
143
144 private static String[] parseExclusionList(String exclusionList) {
145 if (exclusionList == null) {
146 return new String[0];
147 } else {
148 return exclusionList.toLowerCase(Locale.ROOT).split(",");
149 }
150 }
151
152 private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
153 mHost = host;
154 mPort = port;
155 mExclusionList = exclList;
156 mParsedExclusionList = parsedExclList;
157 mPacFileUrl = Uri.EMPTY;
158 }
159
160 /**
161 * A copy constructor to hold proxy properties.
162 */
163 public ProxyInfo(@Nullable ProxyInfo source) {
164 if (source != null) {
165 mHost = source.getHost();
166 mPort = source.getPort();
167 mPacFileUrl = source.mPacFileUrl;
168 mExclusionList = source.getExclusionListAsString();
169 mParsedExclusionList = source.mParsedExclusionList;
170 } else {
171 mHost = null;
172 mPort = 0;
173 mExclusionList = null;
174 mParsedExclusionList = null;
175 mPacFileUrl = Uri.EMPTY;
176 }
177 }
178
179 /**
180 * @hide
181 */
182 public InetSocketAddress getSocketAddress() {
183 InetSocketAddress inetSocketAddress = null;
184 try {
185 inetSocketAddress = new InetSocketAddress(mHost, mPort);
186 } catch (IllegalArgumentException e) { }
187 return inetSocketAddress;
188 }
189
190 /**
191 * Returns the URL of the current PAC script or null if there is
192 * no PAC script.
193 */
194 public Uri getPacFileUrl() {
195 return mPacFileUrl;
196 }
197
198 /**
199 * When configured to use a Direct Proxy this returns the host
200 * of the proxy.
201 */
202 public String getHost() {
203 return mHost;
204 }
205
206 /**
207 * When configured to use a Direct Proxy this returns the port
208 * of the proxy
209 */
210 public int getPort() {
211 return mPort;
212 }
213
214 /**
215 * When configured to use a Direct Proxy this returns the list
216 * of hosts for which the proxy is ignored.
217 */
218 public String[] getExclusionList() {
219 return mParsedExclusionList;
220 }
221
222 /**
223 * comma separated
224 * @hide
225 */
226 @Nullable
227 public String getExclusionListAsString() {
228 return mExclusionList;
229 }
230
231 /**
232 * Return true if the pattern of proxy is valid, otherwise return false.
233 */
234 public boolean isValid() {
235 if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
236 return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
237 mPort == 0 ? "" : Integer.toString(mPort),
238 mExclusionList == null ? "" : mExclusionList);
239 }
240
241 /**
242 * @hide
243 */
244 public java.net.Proxy makeProxy() {
245 java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
246 if (mHost != null) {
247 try {
248 InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
249 proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
250 } catch (IllegalArgumentException e) {
251 }
252 }
253 return proxy;
254 }
255
256 @Override
257 public String toString() {
258 StringBuilder sb = new StringBuilder();
259 if (!Uri.EMPTY.equals(mPacFileUrl)) {
260 sb.append("PAC Script: ");
261 sb.append(mPacFileUrl);
262 }
263 if (mHost != null) {
264 sb.append("[");
265 sb.append(mHost);
266 sb.append("] ");
267 sb.append(Integer.toString(mPort));
268 if (mExclusionList != null) {
269 sb.append(" xl=").append(mExclusionList);
270 }
271 } else {
272 sb.append("[ProxyProperties.mHost == null]");
273 }
274 return sb.toString();
275 }
276
277 @Override
278 public boolean equals(Object o) {
279 if (!(o instanceof ProxyInfo)) return false;
280 ProxyInfo p = (ProxyInfo)o;
281 // If PAC URL is present in either then they must be equal.
282 // Other parameters will only be for fall back.
283 if (!Uri.EMPTY.equals(mPacFileUrl)) {
284 return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
285 }
286 if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
287 return false;
288 }
289 if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
290 return false;
291 }
292 if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
293 return false;
294 }
295 if (mHost != null && p.mHost == null) return false;
296 if (mHost == null && p.mHost != null) return false;
297 if (mPort != p.mPort) return false;
298 return true;
299 }
300
301 /**
302 * Implement the Parcelable interface
303 * @hide
304 */
305 public int describeContents() {
306 return 0;
307 }
308
309 @Override
310 /*
311 * generate hashcode based on significant fields
312 */
313 public int hashCode() {
314 return ((null == mHost) ? 0 : mHost.hashCode())
315 + ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
316 + mPort;
317 }
318
319 /**
320 * Implement the Parcelable interface.
321 * @hide
322 */
323 public void writeToParcel(Parcel dest, int flags) {
324 if (!Uri.EMPTY.equals(mPacFileUrl)) {
325 dest.writeByte((byte)1);
326 mPacFileUrl.writeToParcel(dest, 0);
327 dest.writeInt(mPort);
328 return;
329 } else {
330 dest.writeByte((byte)0);
331 }
332 if (mHost != null) {
333 dest.writeByte((byte)1);
334 dest.writeString(mHost);
335 dest.writeInt(mPort);
336 } else {
337 dest.writeByte((byte)0);
338 }
339 dest.writeString(mExclusionList);
340 dest.writeStringArray(mParsedExclusionList);
341 }
342
343 public static final @android.annotation.NonNull Creator<ProxyInfo> CREATOR =
344 new Creator<ProxyInfo>() {
345 public ProxyInfo createFromParcel(Parcel in) {
346 String host = null;
347 int port = 0;
348 if (in.readByte() != 0) {
349 Uri url = Uri.CREATOR.createFromParcel(in);
350 int localPort = in.readInt();
351 return new ProxyInfo(url, localPort);
352 }
353 if (in.readByte() != 0) {
354 host = in.readString();
355 port = in.readInt();
356 }
357 String exclList = in.readString();
358 String[] parsedExclList = in.createStringArray();
359 ProxyInfo proxyProperties = new ProxyInfo(host, port, exclList, parsedExclList);
360 return proxyProperties;
361 }
362
363 public ProxyInfo[] newArray(int size) {
364 return new ProxyInfo[size];
365 }
366 };
367}