Proxy.java revision 2b4378fef8906b385ee173ebdff9a91d205c7c36
1/* 2 * Copyright (C) 2007 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.SdkConstant; 20import android.annotation.SdkConstant.SdkConstantType; 21import android.content.Context; 22import android.text.TextUtils; 23import android.util.Log; 24 25import java.net.InetSocketAddress; 26import java.net.ProxySelector; 27import java.net.URI; 28import java.util.List; 29import java.util.regex.Matcher; 30import java.util.regex.Pattern; 31 32/** 33 * A convenience class for accessing the user and default proxy 34 * settings. 35 */ 36public final class Proxy { 37 38 private static final String TAG = "Proxy"; 39 40 private static final ProxySelector sDefaultProxySelector; 41 42 /** 43 * Used to notify an app that's caching the default connection proxy 44 * that either the default connection or its proxy has changed. 45 * The intent will have the following extra value:</p> 46 * <ul> 47 * <li><em>EXTRA_PROXY_INFO</em> - The ProxyProperties for the proxy. Non-null, 48 * though if the proxy is undefined the host string 49 * will be empty. 50 * </ul> 51 * 52 * <p class="note">This is a protected intent that can only be sent by the system 53 */ 54 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 55 public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE"; 56 /** {@hide} **/ 57 public static final String EXTRA_PROXY_INFO = "proxy"; 58 59 private static ConnectivityManager sConnectivityManager = null; 60 61 // Hostname / IP REGEX validation 62 // Matches blank input, ips, and domain names 63 private static final String NAME_IP_REGEX = 64 "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*"; 65 66 private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$"; 67 68 private static final Pattern HOSTNAME_PATTERN; 69 70 private static final String EXCLLIST_REGEXP = "$|^(.?" + NAME_IP_REGEX 71 + ")+(,(.?" + NAME_IP_REGEX + "))*$"; 72 73 private static final Pattern EXCLLIST_PATTERN; 74 75 static { 76 HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); 77 EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP); 78 sDefaultProxySelector = ProxySelector.getDefault(); 79 } 80 81 /** 82 * Return the proxy object to be used for the URL given as parameter. 83 * @param ctx A Context used to get the settings for the proxy host. 84 * @param url A URL to be accessed. Used to evaluate exclusion list. 85 * @return Proxy (java.net) object containing the host name. If the 86 * user did not set a hostname it returns the default host. 87 * A null value means that no host is to be used. 88 * {@hide} 89 */ 90 public static final java.net.Proxy getProxy(Context ctx, String url) { 91 String host = ""; 92 if (url != null) { 93 URI uri = URI.create(url); 94 host = uri.getHost(); 95 } 96 97 if (!isLocalHost(host)) { 98 if (sConnectivityManager == null) { 99 sConnectivityManager = (ConnectivityManager)ctx.getSystemService( 100 Context.CONNECTIVITY_SERVICE); 101 } 102 if (sConnectivityManager == null) return java.net.Proxy.NO_PROXY; 103 104 ProxyProperties proxyProperties = sConnectivityManager.getProxy(); 105 106 if (proxyProperties != null) { 107 if (!proxyProperties.isExcluded(host)) { 108 return proxyProperties.makeProxy(); 109 } 110 } 111 } 112 return java.net.Proxy.NO_PROXY; 113 } 114 115 116 /** 117 * Return the proxy host set by the user. 118 * @param ctx A Context used to get the settings for the proxy host. 119 * @return String containing the host name. If the user did not set a host 120 * name it returns the default host. A null value means that no 121 * host is to be used. 122 * @deprecated Use standard java vm proxy values to find the host, port 123 * and exclusion list. This call ignores the exclusion list. 124 */ 125 public static final String getHost(Context ctx) { 126 java.net.Proxy proxy = getProxy(ctx, null); 127 if (proxy == java.net.Proxy.NO_PROXY) return null; 128 try { 129 return ((InetSocketAddress)(proxy.address())).getHostName(); 130 } catch (Exception e) { 131 return null; 132 } 133 } 134 135 /** 136 * Return the proxy port set by the user. 137 * @param ctx A Context used to get the settings for the proxy port. 138 * @return The port number to use or -1 if no proxy is to be used. 139 * @deprecated Use standard java vm proxy values to find the host, port 140 * and exclusion list. This call ignores the exclusion list. 141 */ 142 public static final int getPort(Context ctx) { 143 java.net.Proxy proxy = getProxy(ctx, null); 144 if (proxy == java.net.Proxy.NO_PROXY) return -1; 145 try { 146 return ((InetSocketAddress)(proxy.address())).getPort(); 147 } catch (Exception e) { 148 return -1; 149 } 150 } 151 152 /** 153 * Return the default proxy host specified by the carrier. 154 * @return String containing the host name or null if there is no proxy for 155 * this carrier. 156 * @deprecated Use standard java vm proxy values to find the host, port and 157 * exclusion list. This call ignores the exclusion list and no 158 * longer reports only mobile-data apn-based proxy values. 159 */ 160 public static final String getDefaultHost() { 161 String host = System.getProperty("http.proxyHost"); 162 if (TextUtils.isEmpty(host)) return null; 163 return host; 164 } 165 166 /** 167 * Return the default proxy port specified by the carrier. 168 * @return The port number to be used with the proxy host or -1 if there is 169 * no proxy for this carrier. 170 * @deprecated Use standard java vm proxy values to find the host, port and 171 * exclusion list. This call ignores the exclusion list and no 172 * longer reports only mobile-data apn-based proxy values. 173 */ 174 public static final int getDefaultPort() { 175 if (getDefaultHost() == null) return -1; 176 try { 177 return Integer.parseInt(System.getProperty("http.proxyPort")); 178 } catch (NumberFormatException e) { 179 return -1; 180 } 181 } 182 183 private static final boolean isLocalHost(String host) { 184 if (host == null) { 185 return false; 186 } 187 try { 188 if (host != null) { 189 if (host.equalsIgnoreCase("localhost")) { 190 return true; 191 } 192 if (NetworkUtils.numericToInetAddress(host).isLoopbackAddress()) { 193 return true; 194 } 195 } 196 } catch (IllegalArgumentException iex) { 197 } 198 return false; 199 } 200 201 /** 202 * Validate syntax of hostname, port and exclusion list entries 203 * {@hide} 204 */ 205 public static void validate(String hostname, String port, String exclList) { 206 Matcher match = HOSTNAME_PATTERN.matcher(hostname); 207 Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList); 208 209 if (!match.matches()) { 210 throw new IllegalArgumentException(); 211 } 212 213 if (!listMatch.matches()) { 214 throw new IllegalArgumentException(); 215 } 216 217 if (hostname.length() > 0 && port.length() == 0) { 218 throw new IllegalArgumentException(); 219 } 220 221 if (port.length() > 0) { 222 if (hostname.length() == 0) { 223 throw new IllegalArgumentException(); 224 } 225 int portVal = -1; 226 try { 227 portVal = Integer.parseInt(port); 228 } catch (NumberFormatException ex) { 229 throw new IllegalArgumentException(); 230 } 231 if (portVal <= 0 || portVal > 0xFFFF) { 232 throw new IllegalArgumentException(); 233 } 234 } 235 } 236 237 /** @hide */ 238 public static final void setHttpProxySystemProperty(ProxyProperties p) { 239 String host = null; 240 String port = null; 241 String exclList = null; 242 String pacFileUrl = null; 243 if (p != null) { 244 host = p.getHost(); 245 port = Integer.toString(p.getPort()); 246 exclList = p.getExclusionList(); 247 pacFileUrl = p.getPacFileUrl(); 248 } 249 setHttpProxySystemProperty(host, port, exclList, pacFileUrl); 250 } 251 252 /** @hide */ 253 public static final void setHttpProxySystemProperty(String host, String port, String exclList, 254 String pacFileUrl) { 255 if (exclList != null) exclList = exclList.replace(",", "|"); 256 if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList); 257 if (host != null) { 258 System.setProperty("http.proxyHost", host); 259 System.setProperty("https.proxyHost", host); 260 } else { 261 System.clearProperty("http.proxyHost"); 262 System.clearProperty("https.proxyHost"); 263 } 264 if (port != null) { 265 System.setProperty("http.proxyPort", port); 266 System.setProperty("https.proxyPort", port); 267 } else { 268 System.clearProperty("http.proxyPort"); 269 System.clearProperty("https.proxyPort"); 270 } 271 if (exclList != null) { 272 System.setProperty("http.nonProxyHosts", exclList); 273 System.setProperty("https.nonProxyHosts", exclList); 274 } else { 275 System.clearProperty("http.nonProxyHosts"); 276 System.clearProperty("https.nonProxyHosts"); 277 } 278 if (!TextUtils.isEmpty(pacFileUrl)) { 279 ProxySelector.setDefault(new PacProxySelector()); 280 } else { 281 ProxySelector.setDefault(sDefaultProxySelector); 282 } 283 } 284} 285