2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.text.TextUtils;
24 import java.net.InetSocketAddress;
25 import java.net.URLConnection;
26 import java.util.List;
27 import java.util.Locale;
30 * Describes a proxy configuration.
32 * Proxy configurations are already integrated within the {@code java.net} and
33 * Apache HTTP stack. So {@link URLConnection} and Apache's {@code HttpClient} will use
36 * Other HTTP stacks will need to obtain the proxy info from
37 * {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}.
39 public class ProxyInfo implements Parcelable {
43 private String mExclusionList;
44 private String[] mParsedExclusionList;
46 private Uri mPacFileUrl;
50 public static final String LOCAL_EXCL_LIST = "";
54 public static final int LOCAL_PORT = -1;
58 public static final String LOCAL_HOST = "localhost";
61 * Constructs a {@link ProxyInfo} object that points at a Direct proxy
62 * on the specified host and port.
64 public static ProxyInfo buildDirectProxy(String host, int port) {
65 return new ProxyInfo(host, port, null);
69 * Constructs a {@link ProxyInfo} object that points at a Direct proxy
70 * on the specified host and port.
72 * The proxy will not be used to access any host in exclusion list, exclList.
74 * @param exclList Hosts to exclude using the proxy on connections for. These
75 * hosts can use wildcards such as *.example.com.
77 public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) {
78 String[] array = exclList.toArray(new String[exclList.size()]);
79 return new ProxyInfo(host, port, TextUtils.join(",", array), array);
83 * Construct a {@link ProxyInfo} that will download and run the PAC script
84 * at the specified URL.
86 public static ProxyInfo buildPacProxy(Uri pacUri) {
87 return new ProxyInfo(pacUri);
91 * Create a ProxyProperties that points at a HTTP Proxy.
94 public ProxyInfo(String host, int port, String exclList) {
97 setExclusionList(exclList);
98 mPacFileUrl = Uri.EMPTY;
102 * Create a ProxyProperties that points at a PAC URL.
105 public ProxyInfo(Uri pacFileUrl) {
108 setExclusionList(LOCAL_EXCL_LIST);
109 if (pacFileUrl == null) {
110 throw new NullPointerException();
112 mPacFileUrl = pacFileUrl;
116 * Create a ProxyProperties that points at a PAC URL.
119 public ProxyInfo(String pacFileUrl) {
122 setExclusionList(LOCAL_EXCL_LIST);
123 mPacFileUrl = Uri.parse(pacFileUrl);
127 * Only used in PacManager after Local Proxy is bound.
130 public ProxyInfo(Uri pacFileUrl, int localProxyPort) {
132 mPort = localProxyPort;
133 setExclusionList(LOCAL_EXCL_LIST);
134 if (pacFileUrl == null) {
135 throw new NullPointerException();
137 mPacFileUrl = pacFileUrl;
140 private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
143 mExclusionList = exclList;
144 mParsedExclusionList = parsedExclList;
145 mPacFileUrl = Uri.EMPTY;
148 // copy constructor instead of clone
152 public ProxyInfo(ProxyInfo source) {
153 if (source != null) {
154 mHost = source.getHost();
155 mPort = source.getPort();
156 mPacFileUrl = source.mPacFileUrl;
157 mExclusionList = source.getExclusionListAsString();
158 mParsedExclusionList = source.mParsedExclusionList;
160 mPacFileUrl = Uri.EMPTY;
167 public InetSocketAddress getSocketAddress() {
168 InetSocketAddress inetSocketAddress = null;
170 inetSocketAddress = new InetSocketAddress(mHost, mPort);
171 } catch (IllegalArgumentException e) { }
172 return inetSocketAddress;
176 * Returns the URL of the current PAC script or null if there is
179 public Uri getPacFileUrl() {
184 * When configured to use a Direct Proxy this returns the host
187 public String getHost() {
192 * When configured to use a Direct Proxy this returns the port
195 public int getPort() {
200 * When configured to use a Direct Proxy this returns the list
201 * of hosts for which the proxy is ignored.
203 public String[] getExclusionList() {
204 return mParsedExclusionList;
211 public String getExclusionListAsString() {
212 return mExclusionList;
216 private void setExclusionList(String exclusionList) {
217 mExclusionList = exclusionList;
218 if (mExclusionList == null) {
219 mParsedExclusionList = new String[0];
221 mParsedExclusionList = exclusionList.toLowerCase(Locale.ROOT).split(",");
228 public boolean isValid() {
229 if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
230 return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
231 mPort == 0 ? "" : Integer.toString(mPort),
232 mExclusionList == null ? "" : mExclusionList);
238 public java.net.Proxy makeProxy() {
239 java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
242 InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
243 proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
244 } catch (IllegalArgumentException e) {
251 public String toString() {
252 StringBuilder sb = new StringBuilder();
253 if (!Uri.EMPTY.equals(mPacFileUrl)) {
254 sb.append("PAC Script: ");
255 sb.append(mPacFileUrl);
261 sb.append(Integer.toString(mPort));
262 if (mExclusionList != null) {
263 sb.append(" xl=").append(mExclusionList);
266 sb.append("[ProxyProperties.mHost == null]");
268 return sb.toString();
272 public boolean equals(Object o) {
273 if (!(o instanceof ProxyInfo)) return false;
274 ProxyInfo p = (ProxyInfo)o;
275 // If PAC URL is present in either then they must be equal.
276 // Other parameters will only be for fall back.
277 if (!Uri.EMPTY.equals(mPacFileUrl)) {
278 return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
280 if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
283 if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
286 if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
289 if (mHost != null && p.mHost == null) return false;
290 if (mHost == null && p.mHost != null) return false;
291 if (mPort != p.mPort) return false;
296 * Implement the Parcelable interface
299 public int describeContents() {
305 * generate hashcode based on significant fields
307 public int hashCode() {
308 return ((null == mHost) ? 0 : mHost.hashCode())
309 + ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
314 * Implement the Parcelable interface.
317 public void writeToParcel(Parcel dest, int flags) {
318 if (!Uri.EMPTY.equals(mPacFileUrl)) {
319 dest.writeByte((byte)1);
320 mPacFileUrl.writeToParcel(dest, 0);
321 dest.writeInt(mPort);
324 dest.writeByte((byte)0);
327 dest.writeByte((byte)1);
328 dest.writeString(mHost);
329 dest.writeInt(mPort);
331 dest.writeByte((byte)0);
333 dest.writeString(mExclusionList);
334 dest.writeStringArray(mParsedExclusionList);
337 public static final Creator<ProxyInfo> CREATOR =
338 new Creator<ProxyInfo>() {
339 public ProxyInfo createFromParcel(Parcel in) {
342 if (in.readByte() != 0) {
343 Uri url = Uri.CREATOR.createFromParcel(in);
344 int localPort = in.readInt();
345 return new ProxyInfo(url, localPort);
347 if (in.readByte() != 0) {
348 host = in.readString();
351 String exclList = in.readString();
352 String[] parsedExclList = in.readStringArray();
353 ProxyInfo proxyProperties =
354 new ProxyInfo(host, port, exclList, parsedExclList);
355 return proxyProperties;
358 public ProxyInfo[] newArray(int size) {
359 return new ProxyInfo[size];