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