From 75144448c1f59f167a1030eb650b606447112083 Mon Sep 17 00:00:00 2001 From: Tobias Thierer Date: Wed, 25 Oct 2017 01:01:28 +0100 Subject: Move of OkHttp facade API to new package. This CL moves the classes that make up this facade from libcore.net.http to com.squareup.okhttp.internalandroidapi. In jarjar'ed build targets, this becomes com.android.okhttp.internalandroidapi. This facade constitutes the API via which non-libcore parts of the Android platform (currently framework) may access OkHttp. It's moving because libcore.net.http is already part of libcore, and the overlap of packages is problematic for builds with EXPERIMENTAL_USE_OPENJDK9 set to true. Http{,s}Handler are not currently imported by framework code; this CL moves them back to com.android.okhttp. That package is also where preloaded-classes still expected them to be. Bug: 68220880 Test: CtsLibcoreOkHttpTestCases Change-Id: I6f01c1d0f59db43290dac126f6b6ed2071d7708a --- .../main/java/com/squareup/okhttp/HttpHandler.java | 119 ++++++++++++++ .../java/com/squareup/okhttp/HttpsHandler.java | 96 +++++++++++ .../squareup/okhttp/internalandroidapi/Dns.java | 32 ++++ .../HttpURLConnectionFactory.java | 175 +++++++++++++++++++++ .../com/squareup/okhttp/internalandroidapi/README | 5 + android/main/java/libcore/net/http/Dns.java | 32 ---- .../main/java/libcore/net/http/HttpHandler.java | 125 --------------- .../libcore/net/http/HttpURLConnectionFactory.java | 173 -------------------- .../main/java/libcore/net/http/HttpsHandler.java | 105 ------------- 9 files changed, 427 insertions(+), 435 deletions(-) create mode 100644 android/main/java/com/squareup/okhttp/HttpHandler.java create mode 100644 android/main/java/com/squareup/okhttp/HttpsHandler.java create mode 100644 android/main/java/com/squareup/okhttp/internalandroidapi/Dns.java create mode 100644 android/main/java/com/squareup/okhttp/internalandroidapi/HttpURLConnectionFactory.java create mode 100644 android/main/java/com/squareup/okhttp/internalandroidapi/README delete mode 100644 android/main/java/libcore/net/http/Dns.java delete mode 100644 android/main/java/libcore/net/http/HttpHandler.java delete mode 100644 android/main/java/libcore/net/http/HttpURLConnectionFactory.java delete mode 100644 android/main/java/libcore/net/http/HttpsHandler.java diff --git a/android/main/java/com/squareup/okhttp/HttpHandler.java b/android/main/java/com/squareup/okhttp/HttpHandler.java new file mode 100644 index 0000000..ef9a56b --- /dev/null +++ b/android/main/java/com/squareup/okhttp/HttpHandler.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.squareup.okhttp; + +import com.squareup.okhttp.internal.URLFilter; +import libcore.net.NetworkSecurityPolicy; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.ResponseCache; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class HttpHandler extends URLStreamHandler { + + private final static List CLEARTEXT_ONLY = + Collections.singletonList(ConnectionSpec.CLEARTEXT); + + private static final CleartextURLFilter CLEARTEXT_FILTER = new CleartextURLFilter(); + + private final ConfigAwareConnectionPool configAwareConnectionPool = + ConfigAwareConnectionPool.getInstance(); + + @Override protected URLConnection openConnection(URL url) throws IOException { + return newOkUrlFactory(null /* proxy */).open(url); + } + + @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { + if (url == null || proxy == null) { + throw new IllegalArgumentException("url == null || proxy == null"); + } + return newOkUrlFactory(proxy).open(url); + } + + @Override protected int getDefaultPort() { + return 80; + } + + protected OkUrlFactory newOkUrlFactory(Proxy proxy) { + OkUrlFactory okUrlFactory = createHttpOkUrlFactory(proxy); + // For HttpURLConnections created through java.net.URL Android uses a connection pool that + // is aware when the default network changes so that pooled connections are not re-used when + // the default network changes. + okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); + return okUrlFactory; + } + + /** + * Creates an OkHttpClient suitable for creating {@link java.net.HttpURLConnection} instances on + * Android. + */ + // Visible for android.net.Network. + public static OkUrlFactory createHttpOkUrlFactory(Proxy proxy) { + OkHttpClient client = new OkHttpClient(); + + // Explicitly set the timeouts to infinity. + client.setConnectTimeout(0, TimeUnit.MILLISECONDS); + client.setReadTimeout(0, TimeUnit.MILLISECONDS); + client.setWriteTimeout(0, TimeUnit.MILLISECONDS); + + // Set the default (same protocol) redirect behavior. The default can be overridden for + // each instance using HttpURLConnection.setInstanceFollowRedirects(). + client.setFollowRedirects(HttpURLConnection.getFollowRedirects()); + + // Do not permit http -> https and https -> http redirects. + client.setFollowSslRedirects(false); + + // Permit cleartext traffic only (this is a handler for HTTP, not for HTTPS). + client.setConnectionSpecs(CLEARTEXT_ONLY); + + // When we do not set the Proxy explicitly OkHttp picks up a ProxySelector using + // ProxySelector.getDefault(). + if (proxy != null) { + client.setProxy(proxy); + } + + // OkHttp requires that we explicitly set the response cache. + OkUrlFactory okUrlFactory = new OkUrlFactory(client); + + // Use the installed NetworkSecurityPolicy to determine which requests are permitted over + // http. + OkUrlFactories.setUrlFilter(okUrlFactory, CLEARTEXT_FILTER); + + ResponseCache responseCache = ResponseCache.getDefault(); + if (responseCache != null) { + AndroidInternal.setResponseCache(okUrlFactory, responseCache); + } + return okUrlFactory; + } + + private static final class CleartextURLFilter implements URLFilter { + @Override + public void checkURLPermitted(URL url) throws IOException { + String host = url.getHost(); + if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(host)) { + throw new IOException("Cleartext HTTP traffic to " + host + " not permitted"); + } + } + } +} diff --git a/android/main/java/com/squareup/okhttp/HttpsHandler.java b/android/main/java/com/squareup/okhttp/HttpsHandler.java new file mode 100644 index 0000000..d4c0b8b --- /dev/null +++ b/android/main/java/com/squareup/okhttp/HttpsHandler.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.squareup.okhttp; + +import java.net.Proxy; +import java.util.Collections; +import java.util.List; + +import javax.net.ssl.HttpsURLConnection; + +public final class HttpsHandler extends HttpHandler { + + /** + * The connection spec to use when connecting to an https:// server. Note that Android does + * not set the cipher suites or TLS versions to use so the socket's defaults will be used + * instead. When the SSLSocketFactory is provided by the app or GMS core we will not + * override the enabled ciphers or TLS versions set on the sockets it produces with a + * list hardcoded at release time. This is deliberate. + */ + private static final ConnectionSpec TLS_CONNECTION_SPEC = ConnectionSpecs.builder(true) + .allEnabledCipherSuites() + .allEnabledTlsVersions() + .supportsTlsExtensions(true) + .build(); + + private static final List HTTP_1_1_ONLY = + Collections.singletonList(Protocol.HTTP_1_1); + + private final ConfigAwareConnectionPool configAwareConnectionPool = + ConfigAwareConnectionPool.getInstance(); + + @Override protected int getDefaultPort() { + return 443; + } + + @Override + protected OkUrlFactory newOkUrlFactory(Proxy proxy) { + OkUrlFactory okUrlFactory = createHttpsOkUrlFactory(proxy); + // For HttpsURLConnections created through java.net.URL Android uses a connection pool that + // is aware when the default network changes so that pooled connections are not re-used when + // the default network changes. + okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); + return okUrlFactory; + } + + /** + * Creates an OkHttpClient suitable for creating {@link HttpsURLConnection} instances on + * Android. + */ + // Visible for android.net.Network. + public static OkUrlFactory createHttpsOkUrlFactory(Proxy proxy) { + // The HTTPS OkHttpClient is an HTTP OkHttpClient with extra configuration. + OkUrlFactory okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy); + + // All HTTPS requests are allowed. + OkUrlFactories.setUrlFilter(okUrlFactory, null); + + OkHttpClient okHttpClient = okUrlFactory.client(); + + // Only enable HTTP/1.1 (implies HTTP/1.0). Disable SPDY / HTTP/2.0. + okHttpClient.setProtocols(HTTP_1_1_ONLY); + + okHttpClient.setConnectionSpecs(Collections.singletonList(TLS_CONNECTION_SPEC)); + + // Android support certificate pinning via NetworkSecurityConfig so there is no need to + // also expose OkHttp's mechanism. The OkHttpClient underlying https HttpsURLConnections + // in Android should therefore always use the default certificate pinner, whose set of + // {@code hostNamesToPin} is empty. + okHttpClient.setCertificatePinner(CertificatePinner.DEFAULT); + + // OkHttp does not automatically honor the system-wide HostnameVerifier set with + // HttpsURLConnection.setDefaultHostnameVerifier(). + okUrlFactory.client().setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()); + // OkHttp does not automatically honor the system-wide SSLSocketFactory set with + // HttpsURLConnection.setDefaultSSLSocketFactory(). + // See https://github.com/square/okhttp/issues/184 for details. + okHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory()); + + return okUrlFactory; + } +} diff --git a/android/main/java/com/squareup/okhttp/internalandroidapi/Dns.java b/android/main/java/com/squareup/okhttp/internalandroidapi/Dns.java new file mode 100644 index 0000000..349fade --- /dev/null +++ b/android/main/java/com/squareup/okhttp/internalandroidapi/Dns.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.squareup.okhttp.internalandroidapi; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; + +/** + * A domain name service that resolves IP addresses for host names. + */ +public interface Dns { + /** + * Returns the IP addresses of {@code hostname}, in the order they should + * be attempted. + */ + List lookup(String hostname) throws UnknownHostException; +} diff --git a/android/main/java/com/squareup/okhttp/internalandroidapi/HttpURLConnectionFactory.java b/android/main/java/com/squareup/okhttp/internalandroidapi/HttpURLConnectionFactory.java new file mode 100644 index 0000000..f1da451 --- /dev/null +++ b/android/main/java/com/squareup/okhttp/internalandroidapi/HttpURLConnectionFactory.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.squareup.okhttp.internalandroidapi; + +import com.squareup.okhttp.ConnectionPool; +import com.squareup.okhttp.HttpHandler; +import com.squareup.okhttp.HttpsHandler; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.OkUrlFactories; +import com.squareup.okhttp.OkUrlFactory; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import javax.net.SocketFactory; + +/** + * A way to construct {@link java.net.HttpURLConnection}s that supports some + * configuration on a per-factory or per-connection basis rather than only via + * global static state such as {@link CookieHandler#setDefault(CookieHandler)}. + * The per-factory configuration is optional; if not set, global + * configuration or default behavior is used. + * + * This facade prevents tight coupling with the underlying implementation (on + * top of a particular version of OkHttp). Android code outside of libcore + * should never depend directly on OkHttp. + * + * This abstraction is not suitable for general use. Talk to the maintainers of + * this class before modifying it or adding additional dependencies. + * + * @hide + */ +public final class HttpURLConnectionFactory { + + private ConnectionPool connectionPool; + private com.squareup.okhttp.Dns dns; + + /** + * Sets a new ConnectionPool, specific to this URLFactory and not shared with + * any other connections, with the given configuration. + */ + public void setNewConnectionPool(int maxIdleConnections, long keepAliveDuration, + TimeUnit timeUnit) { + this.connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit); + } + + public void setDns(Dns dns) { + Objects.requireNonNull(dns); + this.dns = new DnsAdapter(dns); + } + + /** + * Opens a connection that uses the system default proxy settings and SocketFactory. + */ + public URLConnection openConnection(URL url) throws IOException { + return internalOpenConnection(url, null /* socketFactory */, null /* proxy */); + } + + /** + * Opens a connection that uses the system default SocketFactory and the specified + * proxy settings. + */ + public URLConnection openConnection(URL url, Proxy proxy) throws IOException { + Objects.requireNonNull(proxy); + return internalOpenConnection(url, null /* socketFactory */, proxy); + } + + /** + * Opens a connection that uses the specified SocketFactory and the system default + * proxy settings. + */ + public URLConnection openConnection(URL url, SocketFactory socketFactory) throws IOException { + Objects.requireNonNull(socketFactory); + return internalOpenConnection(url, socketFactory, null /* proxy */); + } + + /** + * Opens a connection using the specified SocketFactory and the specified proxy + * settings, overriding any system wide configuration. + */ + public URLConnection openConnection(URL url, SocketFactory socketFactory, Proxy proxy) + throws IOException { + Objects.requireNonNull(socketFactory); + Objects.requireNonNull(proxy); + return internalOpenConnection(url, socketFactory, proxy); + } + + private URLConnection internalOpenConnection(URL url, SocketFactory socketFactoryOrNull, + Proxy proxyOrNull) throws IOException { + String protocol = url.getProtocol(); + OkUrlFactory okUrlFactory; + // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache. + // Could this cause unexpected behavior? + if (protocol.equals("http")) { + okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxyOrNull); + } else if (protocol.equals("https")) { + okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(proxyOrNull); + } else { + // OkHttp only supports HTTP and HTTPS. + throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol); + } + + OkHttpClient client = okUrlFactory.client(); + if (connectionPool != null) { + client.setConnectionPool(connectionPool); + } + if (dns != null) { + client.setDns(dns); + } + if (socketFactoryOrNull != null) { + client.setSocketFactory(socketFactoryOrNull); + } + if (proxyOrNull == null) { + return okUrlFactory.open(url); + } else { + return OkUrlFactories.open(okUrlFactory, url, proxyOrNull); + } + } + + /** + * Adapts a {@link Dns} as a {@link com.squareup.okhttp.Dns}. + */ + static final class DnsAdapter implements com.squareup.okhttp.Dns { + private final Dns adaptee; + + DnsAdapter(Dns adaptee) { + this.adaptee = Objects.requireNonNull(adaptee); + } + + @Override + public List lookup(String hostname) throws UnknownHostException { + return adaptee.lookup(hostname); + } + + @Override + public int hashCode() { + return 31 * DnsAdapter.class.hashCode() + adaptee.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof DnsAdapter)) { + return false; + } + return adaptee.equals(((DnsAdapter) obj).adaptee); + } + + @Override + public String toString() { + return adaptee.toString(); + } + } + +} diff --git a/android/main/java/com/squareup/okhttp/internalandroidapi/README b/android/main/java/com/squareup/okhttp/internalandroidapi/README new file mode 100644 index 0000000..e332837 --- /dev/null +++ b/android/main/java/com/squareup/okhttp/internalandroidapi/README @@ -0,0 +1,5 @@ +This package contains a facade over OkHttp that some parts of Android framework are allowed to +depend on. This is not a stable API; it is an attempt to decouple framework code from OkHttp as +much as is practical where public APIs cannot be used. + +Please talk to the maintainers before adding any new dependencies. diff --git a/android/main/java/libcore/net/http/Dns.java b/android/main/java/libcore/net/http/Dns.java deleted file mode 100644 index e42c349..0000000 --- a/android/main/java/libcore/net/http/Dns.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package libcore.net.http; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.List; - -/** - * A domain name service that resolves IP addresses for host names. - */ -public interface Dns { - /** - * Returns the IP addresses of {@code hostname}, in the order they should - * be attempted. - */ - List lookup(String hostname) throws UnknownHostException; -} diff --git a/android/main/java/libcore/net/http/HttpHandler.java b/android/main/java/libcore/net/http/HttpHandler.java deleted file mode 100644 index cf351ad..0000000 --- a/android/main/java/libcore/net/http/HttpHandler.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package libcore.net.http; - -import com.squareup.okhttp.AndroidInternal; -import com.squareup.okhttp.ConnectionSpec; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactories; -import com.squareup.okhttp.OkUrlFactory; -import com.squareup.okhttp.ConfigAwareConnectionPool; -import com.squareup.okhttp.internal.URLFilter; -import libcore.net.NetworkSecurityPolicy; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.ResponseCache; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class HttpHandler extends URLStreamHandler { - - private final static List CLEARTEXT_ONLY = - Collections.singletonList(ConnectionSpec.CLEARTEXT); - - private static final CleartextURLFilter CLEARTEXT_FILTER = new CleartextURLFilter(); - - private final ConfigAwareConnectionPool configAwareConnectionPool = - ConfigAwareConnectionPool.getInstance(); - - @Override protected URLConnection openConnection(URL url) throws IOException { - return newOkUrlFactory(null /* proxy */).open(url); - } - - @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { - if (url == null || proxy == null) { - throw new IllegalArgumentException("url == null || proxy == null"); - } - return newOkUrlFactory(proxy).open(url); - } - - @Override protected int getDefaultPort() { - return 80; - } - - protected OkUrlFactory newOkUrlFactory(Proxy proxy) { - OkUrlFactory okUrlFactory = createHttpOkUrlFactory(proxy); - // For HttpURLConnections created through java.net.URL Android uses a connection pool that - // is aware when the default network changes so that pooled connections are not re-used when - // the default network changes. - okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); - return okUrlFactory; - } - - /** - * Creates an OkHttpClient suitable for creating {@link java.net.HttpURLConnection} instances on - * Android. - */ - // Visible for android.net.Network. - public static OkUrlFactory createHttpOkUrlFactory(Proxy proxy) { - OkHttpClient client = new OkHttpClient(); - - // Explicitly set the timeouts to infinity. - client.setConnectTimeout(0, TimeUnit.MILLISECONDS); - client.setReadTimeout(0, TimeUnit.MILLISECONDS); - client.setWriteTimeout(0, TimeUnit.MILLISECONDS); - - // Set the default (same protocol) redirect behavior. The default can be overridden for - // each instance using HttpURLConnection.setInstanceFollowRedirects(). - client.setFollowRedirects(HttpURLConnection.getFollowRedirects()); - - // Do not permit http -> https and https -> http redirects. - client.setFollowSslRedirects(false); - - // Permit cleartext traffic only (this is a handler for HTTP, not for HTTPS). - client.setConnectionSpecs(CLEARTEXT_ONLY); - - // When we do not set the Proxy explicitly OkHttp picks up a ProxySelector using - // ProxySelector.getDefault(). - if (proxy != null) { - client.setProxy(proxy); - } - - // OkHttp requires that we explicitly set the response cache. - OkUrlFactory okUrlFactory = new OkUrlFactory(client); - - // Use the installed NetworkSecurityPolicy to determine which requests are permitted over - // http. - OkUrlFactories.setUrlFilter(okUrlFactory, CLEARTEXT_FILTER); - - ResponseCache responseCache = ResponseCache.getDefault(); - if (responseCache != null) { - AndroidInternal.setResponseCache(okUrlFactory, responseCache); - } - return okUrlFactory; - } - - private static final class CleartextURLFilter implements URLFilter { - @Override - public void checkURLPermitted(URL url) throws IOException { - String host = url.getHost(); - if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(host)) { - throw new IOException("Cleartext HTTP traffic to " + host + " not permitted"); - } - } - } -} diff --git a/android/main/java/libcore/net/http/HttpURLConnectionFactory.java b/android/main/java/libcore/net/http/HttpURLConnectionFactory.java deleted file mode 100644 index 050405c..0000000 --- a/android/main/java/libcore/net/http/HttpURLConnectionFactory.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package libcore.net.http; - -import com.squareup.okhttp.ConnectionPool; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactories; -import com.squareup.okhttp.OkUrlFactory; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.net.UnknownHostException; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; -import javax.net.SocketFactory; - -/** - * A way to construct {@link java.net.HttpURLConnection}s that supports some - * configuration on a per-factory or per-connection basis rather than only via - * global static state such as {@link CookieHandler#setDefault(CookieHandler)}. - * The per-factory configuration is optional; if not set, global - * configuration or default behavior is used. - * - * This facade prevents tight coupling with the underlying implementation (on - * top of a particular version of OkHttp). Android code outside of libcore - * should never depend directly on OkHttp. - * - * This abstraction is not suitable for general use. Talk to the maintainers of - * this class before modifying it or adding additional dependencies. - * - * @hide - */ -public final class HttpURLConnectionFactory { - - private ConnectionPool connectionPool; - private com.squareup.okhttp.Dns dns; - - /** - * Sets a new ConnectionPool, specific to this URLFactory and not shared with - * any other connections, with the given configuration. - */ - public void setNewConnectionPool(int maxIdleConnections, long keepAliveDuration, - TimeUnit timeUnit) { - this.connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit); - } - - public void setDns(Dns dns) { - Objects.requireNonNull(dns); - this.dns = new DnsAdapter(dns); - } - - /** - * Opens a connection that uses the system default proxy settings and SocketFactory. - */ - public URLConnection openConnection(URL url) throws IOException { - return internalOpenConnection(url, null /* socketFactory */, null /* proxy */); - } - - /** - * Opens a connection that uses the system default SocketFactory and the specified - * proxy settings. - */ - public URLConnection openConnection(URL url, Proxy proxy) throws IOException { - Objects.requireNonNull(proxy); - return internalOpenConnection(url, null /* socketFactory */, proxy); - } - - /** - * Opens a connection that uses the specified SocketFactory and the system default - * proxy settings. - */ - public URLConnection openConnection(URL url, SocketFactory socketFactory) throws IOException { - Objects.requireNonNull(socketFactory); - return internalOpenConnection(url, socketFactory, null /* proxy */); - } - - /** - * Opens a connection using the specified SocketFactory and the specified proxy - * settings, overriding any system wide configuration. - */ - public URLConnection openConnection(URL url, SocketFactory socketFactory, Proxy proxy) - throws IOException { - Objects.requireNonNull(socketFactory); - Objects.requireNonNull(proxy); - return internalOpenConnection(url, socketFactory, proxy); - } - - private URLConnection internalOpenConnection(URL url, SocketFactory socketFactoryOrNull, - Proxy proxyOrNull) throws IOException { - String protocol = url.getProtocol(); - OkUrlFactory okUrlFactory; - // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache. - // Could this cause unexpected behavior? - if (protocol.equals("http")) { - okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxyOrNull); - } else if (protocol.equals("https")) { - okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(proxyOrNull); - } else { - // OkHttp only supports HTTP and HTTPS. - throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol); - } - - OkHttpClient client = okUrlFactory.client(); - if (connectionPool != null) { - client.setConnectionPool(connectionPool); - } - if (dns != null) { - client.setDns(dns); - } - if (socketFactoryOrNull != null) { - client.setSocketFactory(socketFactoryOrNull); - } - if (proxyOrNull == null) { - return okUrlFactory.open(url); - } else { - return OkUrlFactories.open(okUrlFactory, url, proxyOrNull); - } - } - - /** - * Adapts a {@link Dns} as a {@link com.squareup.okhttp.Dns}. - */ - static final class DnsAdapter implements com.squareup.okhttp.Dns { - private final Dns adaptee; - - DnsAdapter(Dns adaptee) { - this.adaptee = Objects.requireNonNull(adaptee); - } - - @Override - public List lookup(String hostname) throws UnknownHostException { - return adaptee.lookup(hostname); - } - - @Override - public int hashCode() { - return 31 * DnsAdapter.class.hashCode() + adaptee.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof DnsAdapter)) { - return false; - } - return adaptee.equals(((DnsAdapter) obj).adaptee); - } - - @Override - public String toString() { - return adaptee.toString(); - } - } - -} diff --git a/android/main/java/libcore/net/http/HttpsHandler.java b/android/main/java/libcore/net/http/HttpsHandler.java deleted file mode 100644 index c50611c..0000000 --- a/android/main/java/libcore/net/http/HttpsHandler.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package libcore.net.http; - -import com.squareup.okhttp.CertificatePinner; -import com.squareup.okhttp.ConnectionSpec; -import com.squareup.okhttp.ConnectionSpecs; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactories; -import com.squareup.okhttp.OkUrlFactory; -import com.squareup.okhttp.Protocol; -import com.squareup.okhttp.ConfigAwareConnectionPool; - -import java.net.Proxy; -import java.util.Collections; -import java.util.List; - -import javax.net.ssl.HttpsURLConnection; - -public final class HttpsHandler extends HttpHandler { - - /** - * The connection spec to use when connecting to an https:// server. Note that Android does - * not set the cipher suites or TLS versions to use so the socket's defaults will be used - * instead. When the SSLSocketFactory is provided by the app or GMS core we will not - * override the enabled ciphers or TLS versions set on the sockets it produces with a - * list hardcoded at release time. This is deliberate. - */ - private static final ConnectionSpec TLS_CONNECTION_SPEC = ConnectionSpecs.builder(true) - .allEnabledCipherSuites() - .allEnabledTlsVersions() - .supportsTlsExtensions(true) - .build(); - - private static final List HTTP_1_1_ONLY = - Collections.singletonList(Protocol.HTTP_1_1); - - private final ConfigAwareConnectionPool configAwareConnectionPool = - ConfigAwareConnectionPool.getInstance(); - - @Override protected int getDefaultPort() { - return 443; - } - - @Override - protected OkUrlFactory newOkUrlFactory(Proxy proxy) { - OkUrlFactory okUrlFactory = createHttpsOkUrlFactory(proxy); - // For HttpsURLConnections created through java.net.URL Android uses a connection pool that - // is aware when the default network changes so that pooled connections are not re-used when - // the default network changes. - okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get()); - return okUrlFactory; - } - - /** - * Creates an OkHttpClient suitable for creating {@link HttpsURLConnection} instances on - * Android. - */ - // Visible for android.net.Network. - public static OkUrlFactory createHttpsOkUrlFactory(Proxy proxy) { - // The HTTPS OkHttpClient is an HTTP OkHttpClient with extra configuration. - OkUrlFactory okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy); - - // All HTTPS requests are allowed. - OkUrlFactories.setUrlFilter(okUrlFactory, null); - - OkHttpClient okHttpClient = okUrlFactory.client(); - - // Only enable HTTP/1.1 (implies HTTP/1.0). Disable SPDY / HTTP/2.0. - okHttpClient.setProtocols(HTTP_1_1_ONLY); - - okHttpClient.setConnectionSpecs(Collections.singletonList(TLS_CONNECTION_SPEC)); - - // Android support certificate pinning via NetworkSecurityConfig so there is no need to - // also expose OkHttp's mechanism. The OkHttpClient underlying https HttpsURLConnections - // in Android should therefore always use the default certificate pinner, whose set of - // {@code hostNamesToPin} is empty. - okHttpClient.setCertificatePinner(CertificatePinner.DEFAULT); - - // OkHttp does not automatically honor the system-wide HostnameVerifier set with - // HttpsURLConnection.setDefaultHostnameVerifier(). - okUrlFactory.client().setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()); - // OkHttp does not automatically honor the system-wide SSLSocketFactory set with - // HttpsURLConnection.setDefaultSSLSocketFactory(). - // See https://github.com/square/okhttp/issues/184 for details. - okHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory()); - - return okUrlFactory; - } -} -- cgit v1.2.3