co.easimart.EasimartURLConnectionHttpClient Maven / Gradle / Ivy
package co.easimart;
import android.net.SSLCertificateSocketFactory;
import android.net.SSLSessionCache;
import co.easimart.http.EasimartHttpBody;
import co.easimart.http.EasimartHttpRequest;
import co.easimart.http.EasimartHttpResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
/** package */ class EasimartURLConnectionHttpClient extends EasimartHttpClient {
private static final String ACCEPT_ENCODING_HEADER = "Accept-encoding";
private static final String GZIP_ENCODING = "gzip";
private static final String CONTENT_LENGTH_HEADER = "Content-Length";
private static final String CONTENT_TYPE_HEADER = "Content-Type";
private int socketOperationTimeout;
public EasimartURLConnectionHttpClient(int socketOperationTimeout, SSLSessionCache sslSessionCache) {
this.socketOperationTimeout = socketOperationTimeout;
HttpsURLConnection.setDefaultSSLSocketFactory(SSLCertificateSocketFactory.getDefault(
socketOperationTimeout, sslSessionCache));
}
@Override
/* package */ EasimartHttpResponse executeInternal(EasimartHttpRequest parseRequest) throws IOException {
HttpURLConnection connection = getRequest(parseRequest);
// Start network connection and write data to server if possible
EasimartHttpBody body = parseRequest.getBody();
if (body != null) {
OutputStream outputStream = connection.getOutputStream();
body.writeTo(outputStream);
outputStream.flush();
outputStream.close();
}
return getResponse(connection);
}
@Override
/* package */ HttpURLConnection getRequest(EasimartHttpRequest httpRequest)
throws IOException {
HttpURLConnection connection;
URL url = new URL(httpRequest.getUrl());
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod(httpRequest.getMethod().toString());
connection.setConnectTimeout(socketOperationTimeout);
connection.setReadTimeout(socketOperationTimeout);
connection.setDoInput(true);
// Don't handle redirects. We copy the setting from AndroidHttpClient.
// For detail, check https://quip.com/Px8jAxnaun2r
connection.setInstanceFollowRedirects(false);
// Set header
for (Map.Entry entry : httpRequest.getAllHeaders().entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
// When URLConnection is powered by OkHttp, by adding this head, OkHttp will turn off its
// transparent decompress which will expose the raw network stream to our interceptors.
if (disableHttpLibraryAutoDecompress()) {
connection.setRequestProperty(ACCEPT_ENCODING_HEADER, GZIP_ENCODING);
}
// Set body
EasimartHttpBody body = httpRequest.getBody();
if (body != null) {
// Content type and content length
connection.setRequestProperty(CONTENT_LENGTH_HEADER, String.valueOf(body.getContentLength()));
connection.setRequestProperty(CONTENT_TYPE_HEADER, body.getContentType());
// We need to set this in order to make URLConnection not buffer our request body so that our
// upload progress callback works.
connection.setFixedLengthStreamingMode(body.getContentLength());
connection.setDoOutput(true);
}
return connection;
}
@Override
/* package */ EasimartHttpResponse getResponse(HttpURLConnection connection)
throws IOException {
// Status code
int statusCode = connection.getResponseCode();
// Content
InputStream content;
if (statusCode < 400) {
content = connection.getInputStream();
} else {
content = connection.getErrorStream();
}
// Total size
int totalSize = connection.getContentLength();
// Reason phrase
String reasonPhrase = connection.getResponseMessage();
// Headers
Map headers = new HashMap<>();
for (Map.Entry> entry : connection.getHeaderFields().entrySet()) {
// The status code's key from header entry is always null(like null=HTTP/1.1 200 OK), since we
// have already had statusCode in EasimartHttpResponse, we just ignore this header entry.
if (entry.getKey() != null && entry.getValue().size() > 0) {
headers.put(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().get(0));
}
}
// Content type
String contentType = connection.getContentType();
return new EasimartHttpResponse.Builder()
.setStatusCode(statusCode)
.setContent(content)
.setTotalSize(totalSize)
.setReasonPhrase(reasonPhrase)
.setHeaders(headers)
.setContentType(contentType)
.build();
}
}