Created
July 25, 2014 07:55
-
-
Save LOG-TAG/d0419bc2207f1a7ec444 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
* Copyright 2013-2014 KdSoft | |
* | |
* 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. | |
*/ | |
package com.kd.lib.droid.net; | |
import com.android.volley.AuthFailureError; | |
import com.android.volley.Request; | |
import com.android.volley.toolbox.HttpStack; | |
import com.kd.lib.droid.ErrorHandler; | |
import com.squareup.okhttp.Cache; | |
import com.squareup.okhttp.Call; | |
import com.squareup.okhttp.Headers; | |
import com.squareup.okhttp.MediaType; | |
import com.squareup.okhttp.OkHttpClient; | |
import com.squareup.okhttp.Protocol; | |
import com.squareup.okhttp.RequestBody; | |
import com.squareup.okhttp.Response; | |
import com.squareup.okhttp.ResponseBody; | |
import org.apache.http.HttpEntity; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.ProtocolVersion; | |
import org.apache.http.StatusLine; | |
import org.apache.http.entity.BasicHttpEntity; | |
import org.apache.http.message.BasicHeader; | |
import org.apache.http.message.BasicHttpResponse; | |
import org.apache.http.message.BasicStatusLine; | |
import java.io.File; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.util.Map; | |
import java.util.concurrent.TimeUnit; | |
import kr.co.kdsoft.droidlib.GlobalContextApplication; | |
/** | |
* Class to integrate volley with okhttp | |
* | |
* @author ceram1 | |
* @see com.android.volley.toolbox.Volley | |
* @see com.squareup.okhttp.OkHttpClient | |
* @since 1.0.05 | |
*/ | |
public class OkHttpStack implements HttpStack { | |
/** | |
* Directory to save cache | |
*/ | |
private static final File CACHE_DIR = GlobalContextApplication.getContext().getCacheDir(); | |
private final OkHttpClient client = new OkHttpClient(); | |
private OkHttpClient mClient; | |
public OkHttpStack() { | |
client.setFollowSslRedirects(true);// Allow http -> https redirect and https -> http redirect | |
try { | |
client.setCache(new Cache(new File(CACHE_DIR, "http_okhttp"), 10 * 1024 * 1024)); | |
} catch (IOException e) { | |
ErrorHandler.handle(e);// Handle with errorhandler | |
} | |
} | |
@Override | |
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) | |
throws IOException, AuthFailureError { | |
final String url = request.getUrl(); | |
final com.squareup.okhttp.Request.Builder okHttpRequestBuilder = new com.squareup.okhttp.Request.Builder(); | |
URL parsedUrl = new URL(url); | |
int timeoutMs = request.getTimeoutMs(); | |
client.setConnectTimeout(timeoutMs, TimeUnit.MILLISECONDS);// OkHttp-UrlConnection -> setConnectionTimeout(long) | |
client.setReadTimeout(timeoutMs, TimeUnit.MILLISECONDS);// OkHttp-UrlConnection -> setReadTimeout(long) | |
final Map<String, String> headers = request.getHeaders(); | |
for (final String name : headers.keySet()) { | |
okHttpRequestBuilder.addHeader(name, headers.get(name)); | |
} | |
for (final String name : additionalHeaders.keySet()) { | |
okHttpRequestBuilder.addHeader(name, additionalHeaders.get(name)); | |
} | |
setConnectionParametersForRequest(okHttpRequestBuilder, request); | |
final com.squareup.okhttp.Request okHttpRequest = okHttpRequestBuilder.build(); | |
final Call okHttpCall = client.newCall(okHttpRequest); | |
final Response okHttpResponse = okHttpCall.execute(); | |
final int responseCode = okHttpResponse.code(); | |
if (responseCode == -1) { | |
// -1 is returned by getResponseCode() if the response code could not be retrieved. | |
// Signal to the caller that something was wrong with the connection. | |
throw new IOException("Could not retrieve response code from HttpUrlConnection."); | |
} | |
final Protocol protocol = okHttpResponse.protocol(); | |
StatusLine responseStatus = new BasicStatusLine(parseProtocol(protocol), okHttpResponse.code(), okHttpResponse.message()); | |
BasicHttpResponse response = new BasicHttpResponse(responseStatus); | |
response.setEntity(entityFromOkHttpResponse(okHttpResponse)); | |
final Headers responseHeaders = okHttpResponse.headers(); | |
for (int i = 0, len = responseHeaders.size(); i < len; i++) { | |
final String name = responseHeaders.name(i), value = responseHeaders.value(i); | |
if (name != null) { | |
response.addHeader(new BasicHeader(name, value)); | |
} | |
} | |
return response; | |
} | |
private static HttpEntity entityFromOkHttpResponse(Response r) { | |
final BasicHttpEntity entity = new BasicHttpEntity(); | |
final ResponseBody body = r.body(); | |
entity.setContent(body.byteStream()); | |
entity.setContentLength(body.contentLength()); | |
entity.setContentEncoding(r.header("Content-Encoding"));// Default action for UrlConnection | |
entity.setContentType(body.contentType().type()); | |
return entity; | |
} | |
@SuppressWarnings("deprecation") | |
private static void setConnectionParametersForRequest(com.squareup.okhttp.Request.Builder builder, Request<?> request) throws IOException, AuthFailureError { | |
switch (request.getMethod()) { | |
case Request.Method.DEPRECATED_GET_OR_POST: | |
// This is the deprecated way that needs to be handled for backwards compatibility. | |
// If the request's post body is null, then the assumption is that the request is | |
// GET. Otherwise, it is assumed that the request is a POST. | |
byte[] postBody = request.getPostBody(); | |
if (postBody != null) { | |
// Prepare output. There is no need to set Content-Length explicitly, | |
// since this is handled by HttpURLConnection using the size of the prepared | |
// output stream. | |
builder.post(RequestBody.create(MediaType.parse(request.getPostBodyContentType()), postBody)); | |
} | |
break; | |
case Request.Method.GET: | |
// Not necessary to set the request method because connection defaults to GET but | |
// being explicit here. | |
builder.get(); | |
break; | |
case Request.Method.DELETE: | |
builder.delete(); | |
break; | |
case Request.Method.POST: | |
builder.post(createRequestBody(request)); | |
break; | |
case Request.Method.PUT: | |
builder.put(createRequestBody(request)); | |
break; | |
case Request.Method.HEAD: | |
builder.head(); | |
break; | |
case Request.Method.OPTIONS: | |
builder.method("OPTIONS", null); | |
break; | |
case Request.Method.TRACE: | |
builder.method("TRACE", null); | |
break; | |
case Request.Method.PATCH: | |
builder.patch(createRequestBody(request)); | |
break; | |
default: | |
throw new IllegalStateException("Unknown method type."); | |
} | |
} | |
private static final ProtocolVersion parseProtocol(final Protocol p) { | |
switch (p) { | |
case HTTP_1_0: | |
return new ProtocolVersion("HTTP", 1, 0); | |
case HTTP_1_1: | |
return new ProtocolVersion("HTTP", 1, 1); | |
case SPDY_3: | |
return new ProtocolVersion("SPDY", 3, 1);//TODO Check volley implementation because I'm not sure if this is okay. | |
case HTTP_2: | |
return new ProtocolVersion("HTTP", 2, 0); | |
} | |
throw new IllegalAccessError("Unkwown protocol"); | |
} | |
private static final RequestBody createRequestBody(Request r) throws AuthFailureError { | |
final byte[] body = r.getBody(); | |
if (body == null) return null; | |
return RequestBody.create(MediaType.parse(r.getBodyContentType()), body); | |
} | |
public OkHttpClient getClient() { | |
return mClient; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment