Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save NitriKx/9dbd7965ed60ea399621d305c8f22c37 to your computer and use it in GitHub Desktop.
Save NitriKx/9dbd7965ed60ea399621d305c8f22c37 to your computer and use it in GitHub Desktop.
OkHttp3 Call Factory for Google AppEngine (useful for using swagger with Retrofit2 template)
package com.teevity.api.lowlevel.impl.googleappengine;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import com.google.common.base.Strings;
import com.teevity.api.lowlevel.impl.ApiException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
/**
*
* @author Benoît Sauvère
*
*/
public class GoogleAppEngineOkHTTP3RetrofitCallFactory implements Call {
Request request;
Headers commonHeaders;
private Integer connectionTimeoutInMs;
private Integer readTimeoutInMs;
GoogleAppEngineOkHTTP3RetrofitCallFactory(Request request, Headers commonHeaders, Integer connectionTimeoutInMs, Integer readTimeoutInMs) {
this.request = request;
this.commonHeaders = commonHeaders;
this.connectionTimeoutInMs = connectionTimeoutInMs;
this.readTimeoutInMs = readTimeoutInMs;
}
@Override
public Request request() {
return request;
}
@Override
public Response execute() throws IOException {
URL url = request.url().url();
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(true);
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestMethod(request.method());
if (connectionTimeoutInMs != null) {
connection.setConnectTimeout(connectionTimeoutInMs);
}
if (readTimeoutInMs != null) {
connection.setConnectTimeout(readTimeoutInMs);
}
Headers headers = request.headers();
if (headers != null) {
for (int i = 0; i < headers.size(); i++) {
String name = headers.name(i);
String value = headers.get(name);
if (Strings.isNullOrEmpty(value) == false) {
connection.setRequestProperty(name, value);
}
}
}
if (request.body() != null && request.body().contentType() != null) {
String bodyContentType = request.body().contentType().toString();
connection.setRequestProperty("Content-Type", bodyContentType);
}
if (commonHeaders != null && commonHeaders.size() > 0) {
for (int i = 0; i < commonHeaders.size(); i++) {
String name = commonHeaders.name(i);
String value = commonHeaders.get(name);
if (Strings.isNullOrEmpty(value) == false) {
connection.setRequestProperty(name, value);
}
}
}
if (request.body() != null) {
BufferedSink outbuf;
outbuf = Okio.buffer(Okio.sink(connection.getOutputStream()));
request.body().writeTo(outbuf);
outbuf.close();
}
final BufferedSource source;
InputStream connectionInputStream = connection.getInputStream();
if (connectionInputStream != null) {
source = Okio.buffer(Okio.source(connectionInputStream));
} else {
source = null;
}
Response response = new Response.Builder()
.code(connection.getResponseCode())
.message(connection.getResponseMessage())
.request(request)
.protocol(Protocol.HTTP_1_1)
.body(new ResponseBody() {
@Override
public MediaType contentType() {
return MediaType.parse(connection.getContentType());
}
@Override
public long contentLength() {
return connection.getContentLengthLong();
}
@Override
public BufferedSource source() {
return source;
}
}).build();
// If the status is a redirection we need to perform the redirection manually (as HttpURLConnection seems to suffer from
// bug over redirections)
int status = response.code();
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) {
String nextLocation = connection.getHeaderField("Location");
if (Strings.isNullOrEmpty(nextLocation) == false) {
Response redirectionResponse = new GoogleAppEngineOkHTTP3RetrofitCallFactory(new Request.Builder()
.url(nextLocation)
.method("GET", null)
.build(),
null,
null,
null).execute();
response = redirectionResponse;
}
}
if (response.isSuccessful() == false) {
throw new ApiException(response);
}
return response;
}
@Override
public void enqueue(Callback responseCallback) {
}
@Override
public void cancel() {
}
@Override
public boolean isExecuted() {
return false;
}
@Override
public boolean isCanceled() {
return false;
}
public static class Factory implements Call.Factory {
private Headers commonHeaders;
private Integer readTimeoutInMs;
private Integer connectionTimeoutInMs;
public Factory(Headers commonHeaders, Integer connectionTimeoutInMs, Integer readTimeoutInMs) {
this.commonHeaders = commonHeaders;
this.connectionTimeoutInMs = connectionTimeoutInMs;
this.readTimeoutInMs = readTimeoutInMs;
}
@Override
public Call newCall(Request request) {
return new GoogleAppEngineOkHTTP3RetrofitCallFactory(request, commonHeaders, connectionTimeoutInMs, readTimeoutInMs);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment