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 java.net.InetSocketAddress; 25 import java.net.URLConnection; 26 import java.util.List; 27 import java.util.Locale; 28 29 /** 30 * Describes a proxy configuration. 31 * 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 34 * them automatically. 35 * 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}. 38 */ 39 public class ProxyInfo implements Parcelable { 40 41 private String mHost; 42 private int mPort; 43 private String mExclusionList; 44 private String[] mParsedExclusionList; 45 46 private Uri mPacFileUrl; 47 /** 48 *@hide 49 */ 50 public static final String LOCAL_EXCL_LIST = ""; 51 /** 52 *@hide 53 */ 54 public static final int LOCAL_PORT = -1; 55 /** 56 *@hide 57 */ 58 public static final String LOCAL_HOST = "localhost"; 59 60 /** 61 * Constructs a {@link ProxyInfo} object that points at a Direct proxy 62 * on the specified host and port. 63 */ buildDirectProxy(String host, int port)64 public static ProxyInfo buildDirectProxy(String host, int port) { 65 return new ProxyInfo(host, port, null); 66 } 67 68 /** 69 * Constructs a {@link ProxyInfo} object that points at a Direct proxy 70 * on the specified host and port. 71 * 72 * The proxy will not be used to access any host in exclusion list, exclList. 73 * 74 * @param exclList Hosts to exclude using the proxy on connections for. These 75 * hosts can use wildcards such as *.example.com. 76 */ buildDirectProxy(String host, int port, List<String> exclList)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); 80 } 81 82 /** 83 * Construct a {@link ProxyInfo} that will download and run the PAC script 84 * at the specified URL. 85 */ buildPacProxy(Uri pacUri)86 public static ProxyInfo buildPacProxy(Uri pacUri) { 87 return new ProxyInfo(pacUri); 88 } 89 90 /** 91 * Create a ProxyProperties that points at a HTTP Proxy. 92 * @hide 93 */ ProxyInfo(String host, int port, String exclList)94 public ProxyInfo(String host, int port, String exclList) { 95 mHost = host; 96 mPort = port; 97 setExclusionList(exclList); 98 mPacFileUrl = Uri.EMPTY; 99 } 100 101 /** 102 * Create a ProxyProperties that points at a PAC URL. 103 * @hide 104 */ ProxyInfo(Uri pacFileUrl)105 public ProxyInfo(Uri pacFileUrl) { 106 mHost = LOCAL_HOST; 107 mPort = LOCAL_PORT; 108 setExclusionList(LOCAL_EXCL_LIST); 109 if (pacFileUrl == null) { 110 throw new NullPointerException(); 111 } 112 mPacFileUrl = pacFileUrl; 113 } 114 115 /** 116 * Create a ProxyProperties that points at a PAC URL. 117 * @hide 118 */ ProxyInfo(String pacFileUrl)119 public ProxyInfo(String pacFileUrl) { 120 mHost = LOCAL_HOST; 121 mPort = LOCAL_PORT; 122 setExclusionList(LOCAL_EXCL_LIST); 123 mPacFileUrl = Uri.parse(pacFileUrl); 124 } 125 126 /** 127 * Only used in PacManager after Local Proxy is bound. 128 * @hide 129 */ ProxyInfo(Uri pacFileUrl, int localProxyPort)130 public ProxyInfo(Uri pacFileUrl, int localProxyPort) { 131 mHost = LOCAL_HOST; 132 mPort = localProxyPort; 133 setExclusionList(LOCAL_EXCL_LIST); 134 if (pacFileUrl == null) { 135 throw new NullPointerException(); 136 } 137 mPacFileUrl = pacFileUrl; 138 } 139 ProxyInfo(String host, int port, String exclList, String[] parsedExclList)140 private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) { 141 mHost = host; 142 mPort = port; 143 mExclusionList = exclList; 144 mParsedExclusionList = parsedExclList; 145 mPacFileUrl = Uri.EMPTY; 146 } 147 148 // copy constructor instead of clone 149 /** 150 * @hide 151 */ ProxyInfo(ProxyInfo source)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; 159 } else { 160 mPacFileUrl = Uri.EMPTY; 161 } 162 } 163 164 /** 165 * @hide 166 */ getSocketAddress()167 public InetSocketAddress getSocketAddress() { 168 InetSocketAddress inetSocketAddress = null; 169 try { 170 inetSocketAddress = new InetSocketAddress(mHost, mPort); 171 } catch (IllegalArgumentException e) { } 172 return inetSocketAddress; 173 } 174 175 /** 176 * Returns the URL of the current PAC script or null if there is 177 * no PAC script. 178 */ getPacFileUrl()179 public Uri getPacFileUrl() { 180 return mPacFileUrl; 181 } 182 183 /** 184 * When configured to use a Direct Proxy this returns the host 185 * of the proxy. 186 */ getHost()187 public String getHost() { 188 return mHost; 189 } 190 191 /** 192 * When configured to use a Direct Proxy this returns the port 193 * of the proxy 194 */ getPort()195 public int getPort() { 196 return mPort; 197 } 198 199 /** 200 * When configured to use a Direct Proxy this returns the list 201 * of hosts for which the proxy is ignored. 202 */ getExclusionList()203 public String[] getExclusionList() { 204 return mParsedExclusionList; 205 } 206 207 /** 208 * comma separated 209 * @hide 210 */ getExclusionListAsString()211 public String getExclusionListAsString() { 212 return mExclusionList; 213 } 214 215 // comma separated setExclusionList(String exclusionList)216 private void setExclusionList(String exclusionList) { 217 mExclusionList = exclusionList; 218 if (mExclusionList == null) { 219 mParsedExclusionList = new String[0]; 220 } else { 221 mParsedExclusionList = exclusionList.toLowerCase(Locale.ROOT).split(","); 222 } 223 } 224 225 /** 226 * @hide 227 */ isValid()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); 233 } 234 235 /** 236 * @hide 237 */ makeProxy()238 public java.net.Proxy makeProxy() { 239 java.net.Proxy proxy = java.net.Proxy.NO_PROXY; 240 if (mHost != null) { 241 try { 242 InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort); 243 proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress); 244 } catch (IllegalArgumentException e) { 245 } 246 } 247 return proxy; 248 } 249 250 @Override toString()251 public String toString() { 252 StringBuilder sb = new StringBuilder(); 253 if (!Uri.EMPTY.equals(mPacFileUrl)) { 254 sb.append("PAC Script: "); 255 sb.append(mPacFileUrl); 256 } 257 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 public static final Creator<ProxyInfo> CREATOR = 338 new Creator<ProxyInfo>() { 339 public ProxyInfo createFromParcel(Parcel in) { 340 String host = null; 341 int port = 0; 342 if (in.readByte() != 0) { 343 Uri url = Uri.CREATOR.createFromParcel(in); 344 int localPort = in.readInt(); 345 return new ProxyInfo(url, localPort); 346 } 347 if (in.readByte() != 0) { 348 host = in.readString(); 349 port = in.readInt(); 350 } 351 String exclList = in.readString(); 352 String[] parsedExclList = in.readStringArray(); 353 ProxyInfo proxyProperties = 354 new ProxyInfo(host, port, exclList, parsedExclList); 355 return proxyProperties; 356 } 357 358 public ProxyInfo[] newArray(int size) { 359 return new ProxyInfo[size]; 360 } 361 }; 362 } 363