blob: f1da45104df95937390c3f1ebcd3360bdf4e0542 [file] [log] [blame]
/*
* 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();
}
}
}