Skip to content

Instantly share code, notes, and snippets.

@swankjesse
Last active May 22, 2019 05:42
Show Gist options
  • Save swankjesse/09721f72039e3a46cf50f94323deb82d to your computer and use it in GitHub Desktop.
Save swankjesse/09721f72039e3a46cf50f94323deb82d to your computer and use it in GitHub Desktop.
/*
* Copyright (C) 2013 Square, Inc.
*
* 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.
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okio.BufferedSink;
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;
/**
* OkHttp 3.14 dropped support for the long-deprecated OkApacheClient class, which allows you to use
* the Apache HTTP client API with OkHttp's implementation. This class does the same thing using
* only public APIs in OkHttp.
*
* <p>Rather than pasting this 250 line gist into your source code, please upgrade to OkHttp's
* request/response API. Your code will be shorter, easier to read, and you'll be able to use
* interceptors.
*/
public final class ObsoleteApacheClient 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".equalsIgnoreCase(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());
}
} else {
body = Util.EMPTY_REQUEST;
}
}
builder.method(method, body);
return builder.build();
}
private static HttpResponse transformResponse(Response response) {
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.proxy();
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 = client.newBuilder()
.proxy(proxy)
.build();
return this;
}
throw new IllegalArgumentException(name);
}
@Override public HttpParams copy() {
throw new UnsupportedOperationException();
}
@Override public boolean removeParameter(String name) {
throw new UnsupportedOperationException();
}
};
private OkHttpClient client;
public ObsoleteApacheClient() {
this(new OkHttpClient());
}
public ObsoleteApacheClient(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) {
}
}
/** Adapts an {@link HttpEntity} to OkHttp's {@link RequestBody}. */
static final class HttpEntityBody extends RequestBody {
static final MediaType DEFAULT_MEDIA_TYPE = MediaType.get("application/octet-stream");
final HttpEntity entity;
final MediaType mediaType;
HttpEntityBody(HttpEntity entity, String contentTypeHeader) {
this.entity = entity;
if (contentTypeHeader != null) {
mediaType = MediaType.parse(contentTypeHeader);
} else if (entity.getContentType() != null) {
mediaType = MediaType.parse(entity.getContentType().getValue());
} else {
// Apache is forgiving and lets you skip specifying a content type with an entity. OkHttp is
// not forgiving so we fall back to a generic type if it's missing.
mediaType = DEFAULT_MEDIA_TYPE;
}
}
@Override public long contentLength() {
return entity.getContentLength();
}
@Override public MediaType contentType() {
return mediaType;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
entity.writeTo(sink.outputStream());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment