blob: c9bca2876b0a23072e413167779f341098bb11b5 [file] [log] [blame]
Robert Greenwalta7dfbd32010-06-15 15:43:39 -07001/*
Wink Saville17465432010-09-21 09:15:35 -07002 * Copyright (C) 2010 The Android Open Source Project
Robert Greenwalta7dfbd32010-06-15 15:43:39 -07003 *
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
Aaron Huanga523b442019-10-02 23:37:02 +080019import android.annotation.NonNull;
20import android.annotation.Nullable;
Artur Satayev0e45d782019-12-10 17:47:52 +000021import android.compat.annotation.UnsupportedAppUsage;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070022import android.os.Parcel;
23import android.os.Parcelable;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -070024import android.text.TextUtils;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070025
Robert Greenwalt98f45832010-09-03 13:02:05 -070026import java.net.InetSocketAddress;
Jason Monk1e3df5d2014-04-25 15:00:09 -040027import java.net.URLConnection;
28import java.util.List;
Elliott Hughes55478822013-08-02 10:00:44 -070029import java.util.Locale;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070030
31/**
Jason Monk1e3df5d2014-04-25 15:00:09 -040032 * Describes a proxy configuration.
33 *
Narayan Kamath439fe7b2014-11-27 18:17:35 +000034 * 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.
Jason Monk1e3df5d2014-04-25 15:00:09 -040037 *
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}.
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070040 */
Jason Monk1e3df5d2014-04-25 15:00:09 -040041public class ProxyInfo implements Parcelable {
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070042
Irina Dumitrescu3a838842018-12-05 16:19:47 +000043 private final String mHost;
44 private final int mPort;
45 private final String mExclusionList;
46 private final String[] mParsedExclusionList;
47 private final Uri mPacFileUrl;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -070048
Jason Monk1e3df5d2014-04-25 15:00:09 -040049 /**
50 *@hide
51 */
Jason Monk43324ee2013-07-03 17:04:33 -040052 public static final String LOCAL_EXCL_LIST = "";
Jason Monk1e3df5d2014-04-25 15:00:09 -040053 /**
54 *@hide
55 */
Jason Monkaf9ded02013-08-23 19:21:25 -040056 public static final int LOCAL_PORT = -1;
Jason Monk1e3df5d2014-04-25 15:00:09 -040057 /**
58 *@hide
59 */
Jason Monk43324ee2013-07-03 17:04:33 -040060 public static final String LOCAL_HOST = "localhost";
61
Jason Monk1e3df5d2014-04-25 15:00:09 -040062 /**
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) {
Jason Monk60a0e162014-05-09 15:16:06 -040089 return new ProxyInfo(pacUri);
Jason Monk1e3df5d2014-04-25 15:00:09 -040090 }
91
92 /**
Aaron Huanga523b442019-10-02 23:37:02 +080093 * 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 /**
Jason Monk1e3df5d2014-04-25 15:00:09 -0400102 * Create a ProxyProperties that points at a HTTP Proxy.
103 * @hide
104 */
Mathew Inwoodf34f05c2018-08-08 14:44:44 +0100105 @UnsupportedAppUsage
Jason Monk1e3df5d2014-04-25 15:00:09 -0400106 public ProxyInfo(String host, int port, String exclList) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700107 mHost = host;
108 mPort = port;
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000109 mExclusionList = exclList;
110 mParsedExclusionList = parseExclusionList(mExclusionList);
Jason Monk60a0e162014-05-09 15:16:06 -0400111 mPacFileUrl = Uri.EMPTY;
112 }
113
114 /**
115 * Create a ProxyProperties that points at a PAC URL.
116 * @hide
117 */
Aaron Huanga523b442019-10-02 23:37:02 +0800118 public ProxyInfo(@NonNull Uri pacFileUrl) {
Jason Monk60a0e162014-05-09 15:16:06 -0400119 mHost = LOCAL_HOST;
120 mPort = LOCAL_PORT;
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000121 mExclusionList = LOCAL_EXCL_LIST;
122 mParsedExclusionList = parseExclusionList(mExclusionList);
Jason Monk60a0e162014-05-09 15:16:06 -0400123 if (pacFileUrl == null) {
124 throw new NullPointerException();
125 }
126 mPacFileUrl = pacFileUrl;
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700127 }
128
Jason Monk1e3df5d2014-04-25 15:00:09 -0400129 /**
Aaron Huang11e7cb22020-11-13 23:55:09 +0800130 * Only used in PacProxyInstaller after Local Proxy is bound.
Jason Monk1e3df5d2014-04-25 15:00:09 -0400131 * @hide
132 */
Aaron Huanga523b442019-10-02 23:37:02 +0800133 public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) {
Jason Monkaf9ded02013-08-23 19:21:25 -0400134 mHost = LOCAL_HOST;
135 mPort = localProxyPort;
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000136 mExclusionList = LOCAL_EXCL_LIST;
137 mParsedExclusionList = parseExclusionList(mExclusionList);
Jason Monk60a0e162014-05-09 15:16:06 -0400138 if (pacFileUrl == null) {
139 throw new NullPointerException();
140 }
Jason Monkaf9ded02013-08-23 19:21:25 -0400141 mPacFileUrl = pacFileUrl;
142 }
143
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000144 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
Jason Monk1e3df5d2014-04-25 15:00:09 -0400152 private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700153 mHost = host;
154 mPort = port;
155 mExclusionList = exclList;
156 mParsedExclusionList = parsedExclList;
Jason Monk60a0e162014-05-09 15:16:06 -0400157 mPacFileUrl = Uri.EMPTY;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700158 }
159
Jason Monk1e3df5d2014-04-25 15:00:09 -0400160 /**
Aaron Huanga523b442019-10-02 23:37:02 +0800161 * A copy constructor to hold proxy properties.
Jason Monk1e3df5d2014-04-25 15:00:09 -0400162 */
Aaron Huanga523b442019-10-02 23:37:02 +0800163 public ProxyInfo(@Nullable ProxyInfo source) {
Irfan Sherifffd151ec2010-08-30 20:37:17 -0700164 if (source != null) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700165 mHost = source.getHost();
166 mPort = source.getPort();
Jason Monk1e3df5d2014-04-25 15:00:09 -0400167 mPacFileUrl = source.mPacFileUrl;
168 mExclusionList = source.getExclusionListAsString();
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700169 mParsedExclusionList = source.mParsedExclusionList;
Sreeram Ramachandran6e24ec72014-05-14 14:45:00 -0700170 } else {
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000171 mHost = null;
172 mPort = 0;
173 mExclusionList = null;
174 mParsedExclusionList = null;
Sreeram Ramachandran6e24ec72014-05-14 14:45:00 -0700175 mPacFileUrl = Uri.EMPTY;
Irfan Sherifffd151ec2010-08-30 20:37:17 -0700176 }
Robert Greenwalt1f1bcfe2010-08-30 10:56:47 -0700177 }
178
Jason Monk1e3df5d2014-04-25 15:00:09 -0400179 /**
180 * @hide
181 */
Robert Greenwalt98f45832010-09-03 13:02:05 -0700182 public InetSocketAddress getSocketAddress() {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700183 InetSocketAddress inetSocketAddress = null;
184 try {
185 inetSocketAddress = new InetSocketAddress(mHost, mPort);
186 } catch (IllegalArgumentException e) { }
187 return inetSocketAddress;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700188 }
Andrew Stadlere55ada72010-08-31 14:28:58 -0700189
Jason Monk1e3df5d2014-04-25 15:00:09 -0400190 /**
191 * Returns the URL of the current PAC script or null if there is
192 * no PAC script.
193 */
194 public Uri getPacFileUrl() {
Jason Monk60a0e162014-05-09 15:16:06 -0400195 return mPacFileUrl;
Jason Monk43324ee2013-07-03 17:04:33 -0400196 }
197
Jason Monk1e3df5d2014-04-25 15:00:09 -0400198 /**
199 * When configured to use a Direct Proxy this returns the host
200 * of the proxy.
201 */
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700202 public String getHost() {
203 return mHost;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700204 }
205
Jason Monk1e3df5d2014-04-25 15:00:09 -0400206 /**
207 * When configured to use a Direct Proxy this returns the port
208 * of the proxy
209 */
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700210 public int getPort() {
211 return mPort;
212 }
213
Jason Monk1e3df5d2014-04-25 15:00:09 -0400214 /**
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 */
Aaron Huanga523b442019-10-02 23:37:02 +0800226 @Nullable
Jason Monk1e3df5d2014-04-25 15:00:09 -0400227 public String getExclusionListAsString() {
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700228 return mExclusionList;
229 }
Andrew Stadlere55ada72010-08-31 14:28:58 -0700230
Jason Monk1e3df5d2014-04-25 15:00:09 -0400231 /**
Aaron Huanga523b442019-10-02 23:37:02 +0800232 * Return true if the pattern of proxy is valid, otherwise return false.
Jason Monk1e3df5d2014-04-25 15:00:09 -0400233 */
Raj Mamadgi08e512b2013-11-11 13:52:58 -0800234 public boolean isValid() {
Jason Monk60a0e162014-05-09 15:16:06 -0400235 if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
Yuhao Zheng12df4ac2014-02-28 17:22:45 -0800236 return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000237 mPort == 0 ? "" : Integer.toString(mPort),
238 mExclusionList == null ? "" : mExclusionList);
Raj Mamadgi08e512b2013-11-11 13:52:58 -0800239 }
240
Jason Monk1e3df5d2014-04-25 15:00:09 -0400241 /**
242 * @hide
243 */
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700244 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;
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700254 }
255
Wink Saville7d857902010-08-27 11:15:18 -0700256 @Override
257 public String toString() {
258 StringBuilder sb = new StringBuilder();
Jason Monk60a0e162014-05-09 15:16:06 -0400259 if (!Uri.EMPTY.equals(mPacFileUrl)) {
Jason Monk43324ee2013-07-03 17:04:33 -0400260 sb.append("PAC Script: ");
261 sb.append(mPacFileUrl);
Paul Jensen12131352014-12-10 15:12:18 -0500262 }
263 if (mHost != null) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700264 sb.append("[");
265 sb.append(mHost);
266 sb.append("] ");
267 sb.append(Integer.toString(mPort));
Robert Greenwalte422ad92010-09-01 09:12:38 -0700268 if (mExclusionList != null) {
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000269 sb.append(" xl=").append(mExclusionList);
Robert Greenwalte422ad92010-09-01 09:12:38 -0700270 }
Wink Savillea7d56572011-09-21 11:05:43 -0700271 } else {
272 sb.append("[ProxyProperties.mHost == null]");
Robert Greenwalte422ad92010-09-01 09:12:38 -0700273 }
Wink Saville7d857902010-08-27 11:15:18 -0700274 return sb.toString();
275 }
276
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700277 @Override
278 public boolean equals(Object o) {
Jason Monk1e3df5d2014-04-25 15:00:09 -0400279 if (!(o instanceof ProxyInfo)) return false;
280 ProxyInfo p = (ProxyInfo)o;
Jason Monk43324ee2013-07-03 17:04:33 -0400281 // If PAC URL is present in either then they must be equal.
282 // Other parameters will only be for fall back.
Jason Monk60a0e162014-05-09 15:16:06 -0400283 if (!Uri.EMPTY.equals(mPacFileUrl)) {
Jason Monk445cea82013-10-10 14:02:51 -0400284 return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
Jason Monk43324ee2013-07-03 17:04:33 -0400285 }
Jason Monk60a0e162014-05-09 15:16:06 -0400286 if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
Jason Monk43324ee2013-07-03 17:04:33 -0400287 return false;
288 }
Jason Monk60a0e162014-05-09 15:16:06 -0400289 if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
290 return false;
291 }
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700292 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
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700301 /**
302 * Implement the Parcelable interface
303 * @hide
304 */
305 public int describeContents() {
306 return 0;
307 }
308
John Wang3e567d52011-04-04 12:35:42 -0700309 @Override
310 /*
311 * generate hashcode based on significant fields
312 */
313 public int hashCode() {
314 return ((null == mHost) ? 0 : mHost.hashCode())
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000315 + ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
316 + mPort;
John Wang3e567d52011-04-04 12:35:42 -0700317 }
318
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700319 /**
320 * Implement the Parcelable interface.
321 * @hide
322 */
Robert Greenwalt1f1bcfe2010-08-30 10:56:47 -0700323 public void writeToParcel(Parcel dest, int flags) {
Jason Monk60a0e162014-05-09 15:16:06 -0400324 if (!Uri.EMPTY.equals(mPacFileUrl)) {
Jason Monk43324ee2013-07-03 17:04:33 -0400325 dest.writeByte((byte)1);
Jason Monk60a0e162014-05-09 15:16:06 -0400326 mPacFileUrl.writeToParcel(dest, 0);
Jason Monk445cea82013-10-10 14:02:51 -0400327 dest.writeInt(mPort);
Jason Monk43324ee2013-07-03 17:04:33 -0400328 return;
329 } else {
330 dest.writeByte((byte)0);
331 }
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700332 if (mHost != null) {
Irfan Sheriff30bdeb32010-09-26 14:54:54 -0700333 dest.writeByte((byte)1);
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700334 dest.writeString(mHost);
335 dest.writeInt(mPort);
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700336 } else {
337 dest.writeByte((byte)0);
338 }
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700339 dest.writeString(mExclusionList);
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700340 dest.writeStringArray(mParsedExclusionList);
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700341 }
342
Jeff Sharkey9286f912019-02-28 12:06:45 -0700343 public static final @android.annotation.NonNull Creator<ProxyInfo> CREATOR =
Jason Monk1e3df5d2014-04-25 15:00:09 -0400344 new Creator<ProxyInfo>() {
345 public ProxyInfo createFromParcel(Parcel in) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700346 String host = null;
347 int port = 0;
Jason Monk43324ee2013-07-03 17:04:33 -0400348 if (in.readByte() != 0) {
Jason Monk60a0e162014-05-09 15:16:06 -0400349 Uri url = Uri.CREATOR.createFromParcel(in);
Jason Monk445cea82013-10-10 14:02:51 -0400350 int localPort = in.readInt();
Jason Monk1e3df5d2014-04-25 15:00:09 -0400351 return new ProxyInfo(url, localPort);
Jason Monk43324ee2013-07-03 17:04:33 -0400352 }
353 if (in.readByte() != 0) {
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700354 host = in.readString();
355 port = in.readInt();
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700356 }
Robert Greenwaltc3c5f862010-10-11 16:00:27 -0700357 String exclList = in.readString();
lucaslincee43542021-01-25 11:01:57 +0800358 String[] parsedExclList = in.createStringArray();
Irina Dumitrescu3a838842018-12-05 16:19:47 +0000359 ProxyInfo proxyProperties = new ProxyInfo(host, port, exclList, parsedExclList);
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700360 return proxyProperties;
361 }
362
Jason Monk1e3df5d2014-04-25 15:00:09 -0400363 public ProxyInfo[] newArray(int size) {
364 return new ProxyInfo[size];
Robert Greenwalta7dfbd32010-06-15 15:43:39 -0700365 }
366 };
Andrew Stadlere55ada72010-08-31 14:28:58 -0700367}