@@ -0,0 +1,179 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2015 Circle Internet Financial
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com .circle .android .api ;
import com .android .volley .AuthFailureError ;
import com .android .volley .Request ;
import com .android .volley .toolbox .HttpStack ;
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 .IOException ;
import java .util .Map ;
import java .util .concurrent .TimeUnit ;
/**
* OkHttp backed {@link com.android.volley.toolbox.HttpStack HttpStack} that does not
* use okhttp-urlconnection
*/
public class OkHttpStack implements HttpStack {
private final OkHttpClient mClient ;
public OkHttpStack (OkHttpClient client ) {
this .mClient = client ;
}
@ Override
public HttpResponse performRequest (Request <?> request , Map <String , String > additionalHeaders )
throws IOException , AuthFailureError {
OkHttpClient client = mClient .clone ();
int timeoutMs = request .getTimeoutMs ();
client .setConnectTimeout (timeoutMs , TimeUnit .MILLISECONDS );
client .setReadTimeout (timeoutMs , TimeUnit .MILLISECONDS );
client .setWriteTimeout (timeoutMs , TimeUnit .MILLISECONDS );
com .squareup .okhttp .Request .Builder okHttpRequestBuilder = new com .squareup .okhttp .Request .Builder ();
okHttpRequestBuilder .url (request .getUrl ());
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 );
com .squareup .okhttp .Request okHttpRequest = okHttpRequestBuilder .build ();
Call okHttpCall = client .newCall (okHttpRequest );
Response okHttpResponse = okHttpCall .execute ();
StatusLine responseStatus = new BasicStatusLine (parseProtocol (okHttpResponse .protocol ()), okHttpResponse .code (), okHttpResponse .message ());
BasicHttpResponse response = new BasicHttpResponse (responseStatus );
response .setEntity (entityFromOkHttpResponse (okHttpResponse ));
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 ) throws IOException {
BasicHttpEntity entity = new BasicHttpEntity ();
ResponseBody body = r .body ();
entity .setContent (body .byteStream ());
entity .setContentLength (body .contentLength ());
entity .setContentEncoding (r .header ("Content-Encoding" ));
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 :
// Ensure backwards compatibility. Volley assumes a request with a null body is a GET.
byte [] postBody = request .getPostBody ();
if (postBody != null ) {
builder .post (RequestBody .create (MediaType .parse (request .getPostBodyContentType ()), postBody ));
}
break ;
case Request .Method .GET :
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 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 );
case HTTP_2 :
return new ProtocolVersion ("HTTP" , 2 , 0 );
}
throw new IllegalAccessError ("Unkwown protocol" );
}
private static RequestBody createRequestBody (Request r ) throws AuthFailureError {
final byte [] body = r .getBody ();
if (body == null ) return null ;
return RequestBody .create (MediaType .parse (r .getBodyContentType ()), body );
}
}