aboutsummaryrefslogtreecommitdiff
path: root/android/main/java/com/squareup
diff options
context:
space:
mode:
authorTobias Thierer <tobiast@google.com>2017-10-30 18:33:01 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-10-30 18:33:01 +0000
commit48afde8fe9e9d49527fe8016be69b362710d5e24 (patch)
tree08d510ae0e06daa63025c3f6526438a147943d07 /android/main/java/com/squareup
parentb41a71cc51a05150a9e39dbf2bbfc88fb91d4c54 (diff)
parent3607e90501aa0c2a980342e1205fd5202488fa02 (diff)
downloadokhttp-48afde8fe9e9d49527fe8016be69b362710d5e24.tar.gz
Merge "Move of OkHttp facade API to new package." am: be2eb23cf4 am: d154dd4e4c
am: 3607e90501 Change-Id: I372cfde359137267b67de89972613006b7cc695c
Diffstat (limited to 'android/main/java/com/squareup')
-rw-r--r--android/main/java/com/squareup/okhttp/HttpHandler.java119
-rw-r--r--android/main/java/com/squareup/okhttp/HttpsHandler.java96
-rw-r--r--android/main/java/com/squareup/okhttp/internalandroidapi/Dns.java32
-rw-r--r--android/main/java/com/squareup/okhttp/internalandroidapi/HttpURLConnectionFactory.java175
-rw-r--r--android/main/java/com/squareup/okhttp/internalandroidapi/README5
5 files changed, 427 insertions, 0 deletions
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<ConnectionSpec> 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<Protocol> 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<InetAddress> 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 <b>optional</b>; 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<InetAddress> 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.