![JAR search and dependency download from the Maven repository](/logo.png)
com.squareup.okhttp.apache.OkApacheClient Maven / Gradle / Ivy
// Copyright 2013 Square, Inc.
package com.squareup.okhttp.apache;
import com.squareup.okhttp.OkHttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.RequestLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.AbstractHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import static java.net.Proxy.Type.HTTP;
import static org.apache.http.HttpVersion.HTTP_1_1;
/**
* Implements Apache's {@link HttpClient} API using {@link OkHttpClient}.
*
* Warning: Many core features of Apache HTTP client are not implemented by this
* API. This includes the keep-alive strategy, cookie store, credentials provider, route planner
* and others.
*/
public class OkApacheClient implements HttpClient {
protected final OkHttpClient client;
private final HttpParams params = new AbstractHttpParams() {
@Override public Object getParameter(String name) {
if (name.equals(ConnRouteParams.DEFAULT_PROXY)) {
Proxy proxy = client.getProxy();
if (proxy == null) {
return null;
}
InetSocketAddress address = (InetSocketAddress) proxy.address();
return new HttpHost(address.getHostName(), address.getPort());
}
throw new IllegalArgumentException(name);
}
@Override public HttpParams setParameter(String name, Object value) {
if (name.equals(ConnRouteParams.DEFAULT_PROXY)) {
HttpHost host = (HttpHost) value;
Proxy proxy = null;
if (host != null) {
proxy = new Proxy(HTTP, new InetSocketAddress(host.getHostName(), host.getPort()));
}
client.setProxy(proxy);
return this;
}
throw new IllegalArgumentException(name);
}
@Override public HttpParams copy() {
throw new UnsupportedOperationException();
}
@Override public boolean removeParameter(String name) {
throw new UnsupportedOperationException();
}
};
public OkApacheClient() {
this(new OkHttpClient());
}
public OkApacheClient(OkHttpClient client) {
this.client = client;
}
/**
* Returns a new HttpURLConnection customized for this application. Subclasses should override
* this to customize the connection.
*/
protected HttpURLConnection openConnection(URL url) {
return client.open(url);
}
@Override public HttpParams getParams() {
return params;
}
@Override public ClientConnectionManager getConnectionManager() {
throw new UnsupportedOperationException();
}
@Override public HttpResponse execute(HttpUriRequest request) throws IOException {
return execute(null, request, (HttpContext) null);
}
@Override public HttpResponse execute(HttpUriRequest request, HttpContext context)
throws IOException {
return execute(null, request, context);
}
@Override public HttpResponse execute(HttpHost host, HttpRequest request) throws IOException {
return execute(host, request, (HttpContext) null);
}
@Override public HttpResponse execute(HttpHost host, HttpRequest request, HttpContext context)
throws IOException {
// Prepare the request headers.
RequestLine requestLine = request.getRequestLine();
URL url = new URL(requestLine.getUri());
HttpURLConnection connection = openConnection(url);
connection.setRequestMethod(requestLine.getMethod());
for (Header header : request.getAllHeaders()) {
connection.addRequestProperty(header.getName(), header.getValue());
}
// Stream the request body.
if (request instanceof HttpEntityEnclosingRequest) {
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
if (entity != null) {
connection.setDoOutput(true);
Header type = entity.getContentType();
if (type != null) {
connection.addRequestProperty(type.getName(), type.getValue());
}
Header encoding = entity.getContentEncoding();
if (encoding != null) {
connection.addRequestProperty(encoding.getName(), encoding.getValue());
}
if (entity.isChunked() || entity.getContentLength() < 0) {
connection.setChunkedStreamingMode(0);
} else if (entity.getContentLength() <= 8192) {
// Buffer short, fixed-length request bodies. This costs memory, but permits the request
// to be transparently retried if there is a connection failure.
connection.addRequestProperty("Content-Length", Long.toString(entity.getContentLength()));
} else {
connection.setFixedLengthStreamingMode((int) entity.getContentLength());
}
entity.writeTo(connection.getOutputStream());
}
}
// Read the response headers.
int responseCode = connection.getResponseCode();
String message = connection.getResponseMessage();
BasicHttpResponse response = new BasicHttpResponse(HTTP_1_1, responseCode, message);
// Get the response body ready to stream.
InputStream responseBody =
responseCode < HttpURLConnection.HTTP_BAD_REQUEST ? connection.getInputStream()
: connection.getErrorStream();
InputStreamEntity entity = new InputStreamEntity(responseBody, connection.getContentLength());
for (int i = 0; true; i++) {
String name = connection.getHeaderFieldKey(i);
if (name == null) {
break;
}
BasicHeader header = new BasicHeader(name, connection.getHeaderField(i));
response.addHeader(header);
if (name.equalsIgnoreCase("Content-Type")) {
entity.setContentType(header);
} else if (name.equalsIgnoreCase("Content-Encoding")) {
entity.setContentEncoding(header);
}
}
response.setEntity(entity);
return response;
}
@Override public T execute(HttpUriRequest request, ResponseHandler extends T> handler)
throws IOException {
return execute(null, request, handler, null);
}
@Override public T execute(HttpUriRequest request, ResponseHandler extends T> handler,
HttpContext context) throws IOException {
return execute(null, request, handler, context);
}
@Override public T execute(HttpHost host, HttpRequest request,
ResponseHandler extends T> handler) throws IOException {
return execute(host, request, handler, null);
}
@Override public T execute(HttpHost host, HttpRequest request,
ResponseHandler extends T> handler, HttpContext context) throws IOException {
HttpResponse response = execute(host, request, context);
try {
return handler.handleResponse(response);
} finally {
consumeContentQuietly(response);
}
}
private static void consumeContentQuietly(HttpResponse response) {
try {
response.getEntity().consumeContent();
} catch (Throwable ignored) {
}
}
}