blob: e3551b0b2ca1d5839d678f18e6b6b1aae41c06fd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Robert Greenwalt434203a2010-10-11 16:00:27 -070019import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
Robert Greenwaltd192dad2010-09-14 09:18:02 -070022import android.text.TextUtils;
Robert Greenwaltd192dad2010-09-14 09:18:02 -070023import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
Jason Monk602b2322013-07-03 17:04:33 -040025import java.net.InetSocketAddress;
26import java.net.ProxySelector;
27import java.net.URI;
Narayan Kamath2b4378f2014-11-03 15:54:34 +000028import java.util.List;
Jason Monk602b2322013-07-03 17:04:33 -040029import java.util.regex.Matcher;
30import java.util.regex.Pattern;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032/**
33 * A convenience class for accessing the user and default proxy
34 * settings.
35 */
Oscar Montemayor16fb7912010-08-02 09:38:48 -070036public final class Proxy {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
Robert Greenwalt434203a2010-10-11 16:00:27 -070038 private static final String TAG = "Proxy";
Dave Bortfb839072009-04-09 15:12:58 -070039
Jason Monk602b2322013-07-03 17:04:33 -040040 private static final ProxySelector sDefaultProxySelector;
Jason Monk602b2322013-07-03 17:04:33 -040041
Robert Greenwalt434203a2010-10-11 16:00:27 -070042 /**
Paul Jensenad823422015-03-11 11:51:46 -040043 * Used to notify an app that's caching the proxy that either the default
44 * connection has changed or any connection's proxy has changed. The new
45 * proxy should be queried using {@link ConnectivityManager#getDefaultProxy()}.
Robert Greenwalt434203a2010-10-11 16:00:27 -070046 *
47 * <p class="note">This is a protected intent that can only be sent by the system
48 */
49 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
50 public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
Jason Monk207900c2014-04-25 15:00:09 -040051 /**
52 * Intent extra included with {@link #PROXY_CHANGE_ACTION} intents.
53 * It describes the new proxy being used (as a {@link ProxyInfo} object).
Paul Jensenad823422015-03-11 11:51:46 -040054 * @deprecated Because {@code PROXY_CHANGE_ACTION} is sent whenever the proxy
55 * for any network on the system changes, applications should always use
56 * {@link ConnectivityManager#getDefaultProxy()} or
57 * {@link ConnectivityManager#getLinkProperties(Network)}.{@link LinkProperties#getHttpProxy()}
58 * to get the proxy for the Network(s) they are using.
Jason Monk207900c2014-04-25 15:00:09 -040059 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -070060 @Deprecated
Jason Monk207900c2014-04-25 15:00:09 -040061 public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
Oscar Montemayor16fb7912010-08-02 09:38:48 -070062
Yuhao Zheng90704842014-02-28 17:22:45 -080063 /** @hide */
64 public static final int PROXY_VALID = 0;
65 /** @hide */
66 public static final int PROXY_HOSTNAME_EMPTY = 1;
67 /** @hide */
68 public static final int PROXY_HOSTNAME_INVALID = 2;
69 /** @hide */
70 public static final int PROXY_PORT_EMPTY = 3;
71 /** @hide */
72 public static final int PROXY_PORT_INVALID = 4;
73 /** @hide */
74 public static final int PROXY_EXCLLIST_INVALID = 5;
75
Robert Greenwaltd192dad2010-09-14 09:18:02 -070076 private static ConnectivityManager sConnectivityManager = null;
77
Oscar Montemayor16fb7912010-08-02 09:38:48 -070078 // Hostname / IP REGEX validation
79 // Matches blank input, ips, and domain names
80 private static final String NAME_IP_REGEX =
81 "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*";
82
83 private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$";
84
85 private static final Pattern HOSTNAME_PATTERN;
86
Yuhao Zheng3dce5af2014-03-03 15:47:06 -080087 private static final String EXCL_REGEX =
88 "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*";
89
90 private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$";
Oscar Montemayor16fb7912010-08-02 09:38:48 -070091
92 private static final Pattern EXCLLIST_PATTERN;
93
94 static {
95 HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
96 EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP);
Jason Monk602b2322013-07-03 17:04:33 -040097 sDefaultProxySelector = ProxySelector.getDefault();
Oscar Montemayor16fb7912010-08-02 09:38:48 -070098 }
99
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700100 /**
101 * Return the proxy object to be used for the URL given as parameter.
102 * @param ctx A Context used to get the settings for the proxy host.
103 * @param url A URL to be accessed. Used to evaluate exclusion list.
104 * @return Proxy (java.net) object containing the host name. If the
105 * user did not set a hostname it returns the default host.
106 * A null value means that no host is to be used.
107 * {@hide}
108 */
109 public static final java.net.Proxy getProxy(Context ctx, String url) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700110 String host = "";
Jason Monk207900c2014-04-25 15:00:09 -0400111 if ((url != null) && !isLocalHost(host)) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700112 URI uri = URI.create(url);
Jason Monk207900c2014-04-25 15:00:09 -0400113 ProxySelector proxySelector = ProxySelector.getDefault();
Robert Greenwalt434203a2010-10-11 16:00:27 -0700114
Jason Monk207900c2014-04-25 15:00:09 -0400115 List<java.net.Proxy> proxyList = proxySelector.select(uri);
Robert Greenwalt434203a2010-10-11 16:00:27 -0700116
Jason Monk207900c2014-04-25 15:00:09 -0400117 if (proxyList.size() > 0) {
118 return proxyList.get(0);
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700119 }
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700120 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700121 return java.net.Proxy.NO_PROXY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700122 }
123
Robert Greenwalt434203a2010-10-11 16:00:27 -0700124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 /**
126 * Return the proxy host set by the user.
127 * @param ctx A Context used to get the settings for the proxy host.
128 * @return String containing the host name. If the user did not set a host
129 * name it returns the default host. A null value means that no
130 * host is to be used.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800131 * @deprecated Use standard java vm proxy values to find the host, port
132 * and exclusion list. This call ignores the exclusion list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700134 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700135 public static final String getHost(Context ctx) {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700136 java.net.Proxy proxy = getProxy(ctx, null);
137 if (proxy == java.net.Proxy.NO_PROXY) return null;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700138 try {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700139 return ((InetSocketAddress)(proxy.address())).getHostName();
140 } catch (Exception e) {
141 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 }
144
145 /**
146 * Return the proxy port set by the user.
147 * @param ctx A Context used to get the settings for the proxy port.
148 * @return The port number to use or -1 if no proxy is to be used.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800149 * @deprecated Use standard java vm proxy values to find the host, port
150 * and exclusion list. This call ignores the exclusion list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700152 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700153 public static final int getPort(Context ctx) {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700154 java.net.Proxy proxy = getProxy(ctx, null);
155 if (proxy == java.net.Proxy.NO_PROXY) return -1;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700156 try {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700157 return ((InetSocketAddress)(proxy.address())).getPort();
158 } catch (Exception e) {
159 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 }
162
163 /**
164 * Return the default proxy host specified by the carrier.
165 * @return String containing the host name or null if there is no proxy for
166 * this carrier.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800167 * @deprecated Use standard java vm proxy values to find the host, port and
168 * exclusion list. This call ignores the exclusion list and no
169 * longer reports only mobile-data apn-based proxy values.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700171 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700172 public static final String getDefaultHost() {
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800173 String host = System.getProperty("http.proxyHost");
174 if (TextUtils.isEmpty(host)) return null;
175 return host;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 }
177
178 /**
179 * Return the default proxy port specified by the carrier.
180 * @return The port number to be used with the proxy host or -1 if there is
181 * no proxy for this carrier.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800182 * @deprecated Use standard java vm proxy values to find the host, port and
183 * exclusion list. This call ignores the exclusion list and no
184 * longer reports only mobile-data apn-based proxy values.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700186 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700187 public static final int getDefaultPort() {
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800188 if (getDefaultHost() == null) return -1;
189 try {
190 return Integer.parseInt(System.getProperty("http.proxyPort"));
191 } catch (NumberFormatException e) {
192 return -1;
193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 }
195
Robert Greenwalt434203a2010-10-11 16:00:27 -0700196 private static final boolean isLocalHost(String host) {
197 if (host == null) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200198 return false;
199 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200200 try {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200201 if (host != null) {
Elliott Hughes6b7af602010-11-04 16:46:00 -0700202 if (host.equalsIgnoreCase("localhost")) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200203 return true;
204 }
Robert Greenwalte5903732011-02-22 16:00:42 -0800205 if (NetworkUtils.numericToInetAddress(host).isLoopbackAddress()) {
206 return true;
Elliott Hughes6b7af602010-11-04 16:46:00 -0700207 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200208 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200209 } catch (IllegalArgumentException iex) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200210 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200211 return false;
212 }
213
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700214 /**
215 * Validate syntax of hostname, port and exclusion list entries
216 * {@hide}
217 */
Yuhao Zheng90704842014-02-28 17:22:45 -0800218 public static int validate(String hostname, String port, String exclList) {
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700219 Matcher match = HOSTNAME_PATTERN.matcher(hostname);
220 Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList);
221
Yuhao Zheng90704842014-02-28 17:22:45 -0800222 if (!match.matches()) return PROXY_HOSTNAME_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700223
Yuhao Zheng90704842014-02-28 17:22:45 -0800224 if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700225
Yuhao Zheng90704842014-02-28 17:22:45 -0800226 if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700227
228 if (port.length() > 0) {
Yuhao Zheng90704842014-02-28 17:22:45 -0800229 if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700230 int portVal = -1;
231 try {
232 portVal = Integer.parseInt(port);
233 } catch (NumberFormatException ex) {
Yuhao Zheng90704842014-02-28 17:22:45 -0800234 return PROXY_PORT_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700235 }
Yuhao Zheng90704842014-02-28 17:22:45 -0800236 if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700237 }
Yuhao Zheng90704842014-02-28 17:22:45 -0800238 return PROXY_VALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700239 }
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700240
Robert Greenwalt434203a2010-10-11 16:00:27 -0700241 /** @hide */
Jason Monk207900c2014-04-25 15:00:09 -0400242 public static final void setHttpProxySystemProperty(ProxyInfo p) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700243 String host = null;
244 String port = null;
245 String exclList = null;
Jason Monk83520b92014-05-09 15:16:06 -0400246 Uri pacFileUrl = Uri.EMPTY;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700247 if (p != null) {
248 host = p.getHost();
249 port = Integer.toString(p.getPort());
Jason Monk207900c2014-04-25 15:00:09 -0400250 exclList = p.getExclusionListAsString();
Jason Monk83520b92014-05-09 15:16:06 -0400251 pacFileUrl = p.getPacFileUrl();
Robert Greenwalt434203a2010-10-11 16:00:27 -0700252 }
Jason Monk602b2322013-07-03 17:04:33 -0400253 setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
Robert Greenwalt434203a2010-10-11 16:00:27 -0700254 }
255
256 /** @hide */
Jason Monk602b2322013-07-03 17:04:33 -0400257 public static final void setHttpProxySystemProperty(String host, String port, String exclList,
Jason Monk83520b92014-05-09 15:16:06 -0400258 Uri pacFileUrl) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700259 if (exclList != null) exclList = exclList.replace(",", "|");
260 if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList);
261 if (host != null) {
262 System.setProperty("http.proxyHost", host);
263 System.setProperty("https.proxyHost", host);
264 } else {
265 System.clearProperty("http.proxyHost");
266 System.clearProperty("https.proxyHost");
267 }
268 if (port != null) {
269 System.setProperty("http.proxyPort", port);
270 System.setProperty("https.proxyPort", port);
271 } else {
272 System.clearProperty("http.proxyPort");
273 System.clearProperty("https.proxyPort");
274 }
275 if (exclList != null) {
276 System.setProperty("http.nonProxyHosts", exclList);
277 System.setProperty("https.nonProxyHosts", exclList);
278 } else {
279 System.clearProperty("http.nonProxyHosts");
280 System.clearProperty("https.nonProxyHosts");
281 }
Jason Monk83520b92014-05-09 15:16:06 -0400282 if (!Uri.EMPTY.equals(pacFileUrl)) {
Jason Monk9ced3cd2013-08-12 16:42:38 -0400283 ProxySelector.setDefault(new PacProxySelector());
Jason Monk602b2322013-07-03 17:04:33 -0400284 } else {
285 ProxySelector.setDefault(sDefaultProxySelector);
286 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700287 }
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700288}