1/* 2 * Copyright (C) 2013 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.os.ServiceManager; 20import android.util.Log; 21 22import com.android.net.IProxyService; 23import com.google.android.collect.Lists; 24 25import java.io.IOException; 26import java.net.InetSocketAddress; 27import java.net.MalformedURLException; 28import java.net.Proxy; 29import java.net.Proxy.Type; 30import java.net.ProxySelector; 31import java.net.SocketAddress; 32import java.net.URI; 33import java.util.List; 34 35/** 36 * @hide 37 */ 38public class PacProxySelector extends ProxySelector { 39 private static final String TAG = "PacProxySelector"; 40 public static final String PROXY_SERVICE = "com.android.net.IProxyService"; 41 private static final String SOCKS = "SOCKS "; 42 private static final String PROXY = "PROXY "; 43 44 private IProxyService mProxyService; 45 private final List<Proxy> mDefaultList; 46 47 public PacProxySelector() { 48 mProxyService = IProxyService.Stub.asInterface( 49 ServiceManager.getService(PROXY_SERVICE)); 50 if (mProxyService == null) { 51 // Added because of b10267814 where mako is restarting. 52 Log.e(TAG, "PacManager: no proxy service"); 53 } 54 mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY); 55 } 56 57 @Override 58 public List<Proxy> select(URI uri) { 59 if (mProxyService == null) { 60 mProxyService = IProxyService.Stub.asInterface( 61 ServiceManager.getService(PROXY_SERVICE)); 62 } 63 if (mProxyService == null) { 64 Log.e(TAG, "select: no proxy service return NO_PROXY"); 65 return Lists.newArrayList(java.net.Proxy.NO_PROXY); 66 } 67 String response = null; 68 String urlString; 69 try { 70 urlString = uri.toURL().toString(); 71 } catch (MalformedURLException e) { 72 urlString = uri.getHost(); 73 } 74 try { 75 response = mProxyService.resolvePacFile(uri.getHost(), urlString); 76 } catch (Exception e) { 77 Log.e(TAG, "Error resolving PAC File", e); 78 } 79 if (response == null) { 80 return mDefaultList; 81 } 82 83 return parseResponse(response); 84 } 85 86 private static List<Proxy> parseResponse(String response) { 87 String[] split = response.split(";"); 88 List<Proxy> ret = Lists.newArrayList(); 89 for (String s : split) { 90 String trimmed = s.trim(); 91 if (trimmed.equals("DIRECT")) { 92 ret.add(java.net.Proxy.NO_PROXY); 93 } else if (trimmed.startsWith(PROXY)) { 94 Proxy proxy = proxyFromHostPort(Type.HTTP, trimmed.substring(PROXY.length())); 95 if (proxy != null) { 96 ret.add(proxy); 97 } 98 } else if (trimmed.startsWith(SOCKS)) { 99 Proxy proxy = proxyFromHostPort(Type.SOCKS, trimmed.substring(SOCKS.length())); 100 if (proxy != null) { 101 ret.add(proxy); 102 } 103 } 104 } 105 if (ret.size() == 0) { 106 ret.add(java.net.Proxy.NO_PROXY); 107 } 108 return ret; 109 } 110 111 private static Proxy proxyFromHostPort(Proxy.Type type, String hostPortString) { 112 try { 113 String[] hostPort = hostPortString.split(":"); 114 String host = hostPort[0]; 115 int port = Integer.parseInt(hostPort[1]); 116 return new Proxy(type, InetSocketAddress.createUnresolved(host, port)); 117 } catch (NumberFormatException|ArrayIndexOutOfBoundsException e) { 118 Log.d(TAG, "Unable to parse proxy " + hostPortString + " " + e); 119 return null; 120 } 121 } 122 123 @Override 124 public void connectFailed(URI uri, SocketAddress address, IOException failure) { 125 126 } 127 128} 129