blob: 4ba7394a4bb28bcb1a2a7a9f25558cdb394bc33f [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;
Artur Satayev26958002019-12-10 17:47:52 +000021import android.compat.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
Robert Greenwaltd192dad2010-09-14 09:18:02 -070023import android.text.TextUtils;
Robert Greenwaltd192dad2010-09-14 09:18:02 -070024import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
Jason Monk602b2322013-07-03 17:04:33 -040026import java.net.InetSocketAddress;
27import java.net.ProxySelector;
28import java.net.URI;
Narayan Kamath2b4378f2014-11-03 15:54:34 +000029import java.util.List;
Jason Monk602b2322013-07-03 17:04:33 -040030import java.util.regex.Matcher;
31import java.util.regex.Pattern;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033/**
34 * A convenience class for accessing the user and default proxy
35 * settings.
36 */
Oscar Montemayor16fb7912010-08-02 09:38:48 -070037public final class Proxy {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
Robert Greenwalt434203a2010-10-11 16:00:27 -070039 private static final String TAG = "Proxy";
Dave Bortfb839072009-04-09 15:12:58 -070040
Jason Monk602b2322013-07-03 17:04:33 -040041 private static final ProxySelector sDefaultProxySelector;
Jason Monk602b2322013-07-03 17:04:33 -040042
Robert Greenwalt434203a2010-10-11 16:00:27 -070043 /**
Paul Jensenad823422015-03-11 11:51:46 -040044 * Used to notify an app that's caching the proxy that either the default
45 * connection has changed or any connection's proxy has changed. The new
46 * proxy should be queried using {@link ConnectivityManager#getDefaultProxy()}.
Robert Greenwalt434203a2010-10-11 16:00:27 -070047 *
48 * <p class="note">This is a protected intent that can only be sent by the system
49 */
50 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
51 public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
Jason Monk207900c2014-04-25 15:00:09 -040052 /**
53 * Intent extra included with {@link #PROXY_CHANGE_ACTION} intents.
54 * It describes the new proxy being used (as a {@link ProxyInfo} object).
Paul Jensenad823422015-03-11 11:51:46 -040055 * @deprecated Because {@code PROXY_CHANGE_ACTION} is sent whenever the proxy
56 * for any network on the system changes, applications should always use
57 * {@link ConnectivityManager#getDefaultProxy()} or
58 * {@link ConnectivityManager#getLinkProperties(Network)}.{@link LinkProperties#getHttpProxy()}
59 * to get the proxy for the Network(s) they are using.
Jason Monk207900c2014-04-25 15:00:09 -040060 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -070061 @Deprecated
Jason Monk207900c2014-04-25 15:00:09 -040062 public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
Oscar Montemayor16fb7912010-08-02 09:38:48 -070063
Yuhao Zheng90704842014-02-28 17:22:45 -080064 /** @hide */
65 public static final int PROXY_VALID = 0;
66 /** @hide */
67 public static final int PROXY_HOSTNAME_EMPTY = 1;
68 /** @hide */
69 public static final int PROXY_HOSTNAME_INVALID = 2;
70 /** @hide */
71 public static final int PROXY_PORT_EMPTY = 3;
72 /** @hide */
73 public static final int PROXY_PORT_INVALID = 4;
74 /** @hide */
75 public static final int PROXY_EXCLLIST_INVALID = 5;
76
Robert Greenwaltd192dad2010-09-14 09:18:02 -070077 private static ConnectivityManager sConnectivityManager = null;
78
Oscar Montemayor16fb7912010-08-02 09:38:48 -070079 // Hostname / IP REGEX validation
80 // Matches blank input, ips, and domain names
81 private static final String NAME_IP_REGEX =
82 "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*";
83
84 private static final String HOSTNAME_REGEXP = "^$|^" + NAME_IP_REGEX + "$";
85
86 private static final Pattern HOSTNAME_PATTERN;
87
Yuhao Zheng3dce5af2014-03-03 15:47:06 -080088 private static final String EXCL_REGEX =
89 "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*";
90
91 private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$";
Oscar Montemayor16fb7912010-08-02 09:38:48 -070092
93 private static final Pattern EXCLLIST_PATTERN;
94
95 static {
96 HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
97 EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP);
Jason Monk602b2322013-07-03 17:04:33 -040098 sDefaultProxySelector = ProxySelector.getDefault();
Oscar Montemayor16fb7912010-08-02 09:38:48 -070099 }
100
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700101 /**
102 * Return the proxy object to be used for the URL given as parameter.
103 * @param ctx A Context used to get the settings for the proxy host.
104 * @param url A URL to be accessed. Used to evaluate exclusion list.
105 * @return Proxy (java.net) object containing the host name. If the
106 * user did not set a hostname it returns the default host.
107 * A null value means that no host is to be used.
108 * {@hide}
109 */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100110 @UnsupportedAppUsage
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700111 public static final java.net.Proxy getProxy(Context ctx, String url) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700112 String host = "";
Jason Monk207900c2014-04-25 15:00:09 -0400113 if ((url != null) && !isLocalHost(host)) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700114 URI uri = URI.create(url);
Jason Monk207900c2014-04-25 15:00:09 -0400115 ProxySelector proxySelector = ProxySelector.getDefault();
Robert Greenwalt434203a2010-10-11 16:00:27 -0700116
Jason Monk207900c2014-04-25 15:00:09 -0400117 List<java.net.Proxy> proxyList = proxySelector.select(uri);
Robert Greenwalt434203a2010-10-11 16:00:27 -0700118
Jason Monk207900c2014-04-25 15:00:09 -0400119 if (proxyList.size() > 0) {
120 return proxyList.get(0);
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700121 }
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700122 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700123 return java.net.Proxy.NO_PROXY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700124 }
125
Robert Greenwalt434203a2010-10-11 16:00:27 -0700126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 /**
128 * Return the proxy host set by the user.
129 * @param ctx A Context used to get the settings for the proxy host.
130 * @return String containing the host name. If the user did not set a host
131 * name it returns the default host. A null value means that no
132 * host is to be used.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800133 * @deprecated Use standard java vm proxy values to find the host, port
134 * and exclusion list. This call ignores the exclusion list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700136 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700137 public static final String getHost(Context ctx) {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700138 java.net.Proxy proxy = getProxy(ctx, null);
139 if (proxy == java.net.Proxy.NO_PROXY) return null;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700140 try {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700141 return ((InetSocketAddress)(proxy.address())).getHostName();
142 } catch (Exception e) {
143 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 }
146
147 /**
148 * Return the proxy port set by the user.
149 * @param ctx A Context used to get the settings for the proxy port.
150 * @return The port number to use or -1 if no proxy is to be used.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800151 * @deprecated Use standard java vm proxy values to find the host, port
152 * and exclusion list. This call ignores the exclusion list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700154 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700155 public static final int getPort(Context ctx) {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700156 java.net.Proxy proxy = getProxy(ctx, null);
157 if (proxy == java.net.Proxy.NO_PROXY) return -1;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700158 try {
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700159 return ((InetSocketAddress)(proxy.address())).getPort();
160 } catch (Exception e) {
161 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 }
164
165 /**
166 * Return the default proxy host specified by the carrier.
167 * @return String containing the host name or null if there is no proxy for
168 * this carrier.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800169 * @deprecated Use standard java vm proxy values to find the host, port and
170 * exclusion list. This call ignores the exclusion list and no
171 * longer reports only mobile-data apn-based proxy values.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700173 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700174 public static final String getDefaultHost() {
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800175 String host = System.getProperty("http.proxyHost");
176 if (TextUtils.isEmpty(host)) return null;
177 return host;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 }
179
180 /**
181 * Return the default proxy port specified by the carrier.
182 * @return The port number to be used with the proxy host or -1 if there is
183 * no proxy for this carrier.
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800184 * @deprecated Use standard java vm proxy values to find the host, port and
185 * exclusion list. This call ignores the exclusion list and no
186 * longer reports only mobile-data apn-based proxy values.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700188 @Deprecated
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700189 public static final int getDefaultPort() {
Robert Greenwalt778c0ba2010-12-14 11:55:36 -0800190 if (getDefaultHost() == null) return -1;
191 try {
192 return Integer.parseInt(System.getProperty("http.proxyPort"));
193 } catch (NumberFormatException e) {
194 return -1;
195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 }
197
Robert Greenwalt434203a2010-10-11 16:00:27 -0700198 private static final boolean isLocalHost(String host) {
199 if (host == null) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200200 return false;
201 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200202 try {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200203 if (host != null) {
Elliott Hughes6b7af602010-11-04 16:46:00 -0700204 if (host.equalsIgnoreCase("localhost")) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200205 return true;
206 }
Robert Greenwalte5903732011-02-22 16:00:42 -0800207 if (NetworkUtils.numericToInetAddress(host).isLoopbackAddress()) {
208 return true;
Elliott Hughes6b7af602010-11-04 16:46:00 -0700209 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200210 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200211 } catch (IllegalArgumentException iex) {
Andreas Sandblad2986f852010-06-16 13:10:49 +0200212 }
Andreas Sandblad2986f852010-06-16 13:10:49 +0200213 return false;
214 }
215
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700216 /**
217 * Validate syntax of hostname, port and exclusion list entries
218 * {@hide}
219 */
Yuhao Zheng90704842014-02-28 17:22:45 -0800220 public static int validate(String hostname, String port, String exclList) {
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700221 Matcher match = HOSTNAME_PATTERN.matcher(hostname);
222 Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList);
223
Yuhao Zheng90704842014-02-28 17:22:45 -0800224 if (!match.matches()) return PROXY_HOSTNAME_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700225
Yuhao Zheng90704842014-02-28 17:22:45 -0800226 if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700227
Yuhao Zheng90704842014-02-28 17:22:45 -0800228 if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700229
230 if (port.length() > 0) {
Yuhao Zheng90704842014-02-28 17:22:45 -0800231 if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700232 int portVal = -1;
233 try {
234 portVal = Integer.parseInt(port);
235 } catch (NumberFormatException ex) {
Yuhao Zheng90704842014-02-28 17:22:45 -0800236 return PROXY_PORT_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700237 }
Yuhao Zheng90704842014-02-28 17:22:45 -0800238 if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700239 }
Yuhao Zheng90704842014-02-28 17:22:45 -0800240 return PROXY_VALID;
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700241 }
Robert Greenwaltd192dad2010-09-14 09:18:02 -0700242
Robert Greenwalt434203a2010-10-11 16:00:27 -0700243 /** @hide */
Mathew Inwood53f089f2018-08-08 14:44:44 +0100244 @UnsupportedAppUsage
Jason Monk207900c2014-04-25 15:00:09 -0400245 public static final void setHttpProxySystemProperty(ProxyInfo p) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700246 String host = null;
247 String port = null;
248 String exclList = null;
Jason Monk83520b92014-05-09 15:16:06 -0400249 Uri pacFileUrl = Uri.EMPTY;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700250 if (p != null) {
251 host = p.getHost();
252 port = Integer.toString(p.getPort());
Jason Monk207900c2014-04-25 15:00:09 -0400253 exclList = p.getExclusionListAsString();
Jason Monk83520b92014-05-09 15:16:06 -0400254 pacFileUrl = p.getPacFileUrl();
Robert Greenwalt434203a2010-10-11 16:00:27 -0700255 }
Jason Monk602b2322013-07-03 17:04:33 -0400256 setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
Robert Greenwalt434203a2010-10-11 16:00:27 -0700257 }
258
259 /** @hide */
Jason Monk602b2322013-07-03 17:04:33 -0400260 public static final void setHttpProxySystemProperty(String host, String port, String exclList,
Jason Monk83520b92014-05-09 15:16:06 -0400261 Uri pacFileUrl) {
Robert Greenwalt434203a2010-10-11 16:00:27 -0700262 if (exclList != null) exclList = exclList.replace(",", "|");
263 if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList);
264 if (host != null) {
265 System.setProperty("http.proxyHost", host);
266 System.setProperty("https.proxyHost", host);
267 } else {
268 System.clearProperty("http.proxyHost");
269 System.clearProperty("https.proxyHost");
270 }
271 if (port != null) {
272 System.setProperty("http.proxyPort", port);
273 System.setProperty("https.proxyPort", port);
274 } else {
275 System.clearProperty("http.proxyPort");
276 System.clearProperty("https.proxyPort");
277 }
278 if (exclList != null) {
279 System.setProperty("http.nonProxyHosts", exclList);
280 System.setProperty("https.nonProxyHosts", exclList);
281 } else {
282 System.clearProperty("http.nonProxyHosts");
283 System.clearProperty("https.nonProxyHosts");
284 }
Jason Monk83520b92014-05-09 15:16:06 -0400285 if (!Uri.EMPTY.equals(pacFileUrl)) {
Jason Monk9ced3cd2013-08-12 16:42:38 -0400286 ProxySelector.setDefault(new PacProxySelector());
Jason Monk602b2322013-07-03 17:04:33 -0400287 } else {
288 ProxySelector.setDefault(sDefaultProxySelector);
289 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700290 }
Oscar Montemayor16fb7912010-08-02 09:38:48 -0700291}