| // Copyright 2013 Square, Inc. |
| package com.squareup.okhttp.apache; |
| |
| import com.squareup.okhttp.Headers; |
| import com.squareup.okhttp.OkHttpClient; |
| import com.squareup.okhttp.Request; |
| import com.squareup.okhttp.RequestBody; |
| import com.squareup.okhttp.Response; |
| import com.squareup.okhttp.ResponseBody; |
| import java.io.IOException; |
| import java.net.InetSocketAddress; |
| import java.net.Proxy; |
| 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.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}. |
| * <p> |
| * <strong>Warning:</strong> 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 final class OkApacheClient implements HttpClient { |
| private static Request transformRequest(HttpRequest request) { |
| Request.Builder builder = new Request.Builder(); |
| |
| RequestLine requestLine = request.getRequestLine(); |
| String method = requestLine.getMethod(); |
| builder.url(requestLine.getUri()); |
| |
| String contentType = null; |
| for (Header header : request.getAllHeaders()) { |
| String name = header.getName(); |
| if ("Content-Type".equals(name)) { |
| contentType = header.getValue(); |
| } else { |
| builder.header(name, header.getValue()); |
| } |
| } |
| |
| RequestBody body = null; |
| if (request instanceof HttpEntityEnclosingRequest) { |
| HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); |
| if (entity != null) { |
| // Wrap the entity in a custom Body which takes care of the content, length, and type. |
| body = new HttpEntityBody(entity, contentType); |
| |
| Header encoding = entity.getContentEncoding(); |
| if (encoding != null) { |
| builder.header(encoding.getName(), encoding.getValue()); |
| } |
| } |
| } |
| builder.method(method, body); |
| |
| return builder.build(); |
| } |
| |
| private static HttpResponse transformResponse(Response response) throws IOException { |
| int code = response.code(); |
| String message = response.message(); |
| BasicHttpResponse httpResponse = new BasicHttpResponse(HTTP_1_1, code, message); |
| |
| ResponseBody body = response.body(); |
| InputStreamEntity entity = new InputStreamEntity(body.byteStream(), body.contentLength()); |
| httpResponse.setEntity(entity); |
| |
| Headers headers = response.headers(); |
| for (int i = 0, size = headers.size(); i < size; i++) { |
| String name = headers.name(i); |
| String value = headers.value(i); |
| httpResponse.addHeader(name, value); |
| if ("Content-Type".equalsIgnoreCase(name)) { |
| entity.setContentType(value); |
| } else if ("Content-Encoding".equalsIgnoreCase(name)) { |
| entity.setContentEncoding(value); |
| } |
| } |
| |
| return httpResponse; |
| } |
| |
| 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(); |
| } |
| }; |
| |
| private final OkHttpClient client; |
| |
| public OkApacheClient() { |
| this(new OkHttpClient()); |
| } |
| |
| public OkApacheClient(OkHttpClient client) { |
| this.client = client; |
| } |
| |
| @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 { |
| Request okRequest = transformRequest(request); |
| Response okResponse = client.newCall(okRequest).execute(); |
| return transformResponse(okResponse); |
| } |
| |
| @Override public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> handler) |
| throws IOException { |
| return execute(null, request, handler, null); |
| } |
| |
| @Override public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> handler, |
| HttpContext context) throws IOException { |
| return execute(null, request, handler, context); |
| } |
| |
| @Override public <T> T execute(HttpHost host, HttpRequest request, |
| ResponseHandler<? extends T> handler) throws IOException { |
| return execute(host, request, handler, null); |
| } |
| |
| @Override public <T> 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) { |
| } |
| } |
| } |