1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.squareup.okhttp; 19 20 import com.squareup.okhttp.internal.URLFilter; 21 import libcore.net.NetworkSecurityPolicy; 22 import java.io.IOException; 23 import java.net.HttpURLConnection; 24 import java.net.Proxy; 25 import java.net.ResponseCache; 26 import java.net.URL; 27 import java.net.URLConnection; 28 import java.net.URLStreamHandler; 29 import java.util.Collections; 30 import java.util.List; 31 import java.util.concurrent.TimeUnit; 32 33 public class HttpHandler extends URLStreamHandler { 34 35 private final static List<ConnectionSpec> CLEARTEXT_ONLY = 36 Collections.singletonList(ConnectionSpec.CLEARTEXT); 37 38 private static final CleartextURLFilter CLEARTEXT_FILTER = new CleartextURLFilter(); 39 40 private final ConfigAwareConnectionPool configAwareConnectionPool = 41 ConfigAwareConnectionPool.getInstance(); 42 43 @Override protected URLConnection openConnection(URL url) throws IOException { 44 return newOkUrlFactory(null /* proxy */).open(url); 45 } 46 47 @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { 48 if (url == null || proxy == null) { 49 throw new IllegalArgumentException("url == null || proxy == null"); 50 } 51 return newOkUrlFactory(proxy).open(url); 52 } 53 54 @Override protected int getDefaultPort() { 55 return 80; 56 } 57 58 protected OkUrlFactory newOkUrlFactory(Proxy proxy) { 59 OkUrlFactory okUrlFactory = createHttpOkUrlFactory(proxy); 60 // For HttpURLConnections created through java.net.URL Android uses a connection pool that 61 // is aware when the default network changes so that pooled connections are not re-used when 62 // the default network changes. 63 okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); 64 return okUrlFactory; 65 } 66 67 /** 68 * Creates an OkHttpClient suitable for creating {@link java.net.HttpURLConnection} instances on 69 * Android. 70 */ 71 // Visible for android.net.Network. 72 public static OkUrlFactory createHttpOkUrlFactory(Proxy proxy) { 73 OkHttpClient client = new OkHttpClient(); 74 75 // Explicitly set the timeouts to infinity. 76 client.setConnectTimeout(0, TimeUnit.MILLISECONDS); 77 client.setReadTimeout(0, TimeUnit.MILLISECONDS); 78 client.setWriteTimeout(0, TimeUnit.MILLISECONDS); 79 80 // Set the default (same protocol) redirect behavior. The default can be overridden for 81 // each instance using HttpURLConnection.setInstanceFollowRedirects(). 82 client.setFollowRedirects(HttpURLConnection.getFollowRedirects()); 83 84 // Do not permit http -> https and https -> http redirects. 85 client.setFollowSslRedirects(false); 86 87 // Permit cleartext traffic only (this is a handler for HTTP, not for HTTPS). 88 client.setConnectionSpecs(CLEARTEXT_ONLY); 89 90 // When we do not set the Proxy explicitly OkHttp picks up a ProxySelector using 91 // ProxySelector.getDefault(). 92 if (proxy != null) { 93 client.setProxy(proxy); 94 } 95 96 // OkHttp requires that we explicitly set the response cache. 97 OkUrlFactory okUrlFactory = new OkUrlFactory(client); 98 99 // Use the installed NetworkSecurityPolicy to determine which requests are permitted over 100 // http. 101 OkUrlFactories.setUrlFilter(okUrlFactory, CLEARTEXT_FILTER); 102 103 ResponseCache responseCache = ResponseCache.getDefault(); 104 if (responseCache != null) { 105 AndroidInternal.setResponseCache(okUrlFactory, responseCache); 106 } 107 return okUrlFactory; 108 } 109 110 private static final class CleartextURLFilter implements URLFilter { 111 @Override 112 public void checkURLPermitted(URL url) throws IOException { 113 String host = url.getHost(); 114 if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(host)) { 115 throw new IOException("Cleartext HTTP traffic to " + host + " not permitted"); 116 } 117 } 118 } 119 } 120