Created
August 31, 2017 15:17
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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