com.objectivetruth.uoitlibrarybooking.app.networking.OkHttp3Stack.java Source code

Java tutorial

Introduction

Here is the source code for com.objectivetruth.uoitlibrarybooking.app.networking.OkHttp3Stack.java

Source

package com.objectivetruth.uoitlibrarybooking.app.networking;

/**
 * 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.
 */

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.toolbox.HttpStack;
import okhttp3.*;
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 timber.log.Timber;

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 OkHttp3Stack implements HttpStack {
    final static private String USER_AGENT_VALUE = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0";
    private CookieJar cookieJar = new CustomCookieJar();

    @Override
    public HttpResponse performRequest(com.android.volley.Request<?> request, Map<String, String> additionalHeaders)
            throws IOException, AuthFailureError {
        String USER_AGENT_KEY_NAME = "User-Agent";

        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        int timeoutMs = request.getTimeoutMs();

        clientBuilder.connectTimeout(timeoutMs, TimeUnit.MILLISECONDS);
        clientBuilder.readTimeout(timeoutMs, TimeUnit.MILLISECONDS);
        clientBuilder.writeTimeout(timeoutMs, TimeUnit.MILLISECONDS);
        //clientBuilder.followRedirects(false);
        clientBuilder.cookieJar(cookieJar);

        okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder();
        okHttpRequestBuilder.url(request.getUrl());

        Map<String, String> headers = request.getHeaders();
        for (final String name : headers.keySet()) {
            String outgoingHeaderValue = headers.get(name);
            okHttpRequestBuilder.addHeader(name, outgoingHeaderValue);
            Timber.v("Outgoing Header:" + name + ": " + outgoingHeaderValue);
        }
        for (final String name : additionalHeaders.keySet()) {
            okHttpRequestBuilder.addHeader(name, additionalHeaders.get(name));
            Timber.v("Outgoing Additional Header:" + name + ": " + additionalHeaders.get(name));
        }

        Timber.d("Injecting User-Agent into request(will overwrite any other user-agent headers placed)");
        okHttpRequestBuilder.addHeader(USER_AGENT_KEY_NAME, USER_AGENT_VALUE);
        Timber.v("Outgoing Header:" + USER_AGENT_KEY_NAME + ": " + USER_AGENT_VALUE);

        setConnectionParametersForRequest(okHttpRequestBuilder, request);

        OkHttpClient client = clientBuilder.build();
        okhttp3.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) {
                Timber.v("Incoming Header:" + name + ": " + value);
                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"));

        if (body.contentType() != null) {
            entity.setContentType(body.contentType().type());
        }
        return entity;
    }

    @SuppressWarnings("deprecation")
    private static void setConnectionParametersForRequest(okhttp3.Request.Builder builder,
            com.android.volley.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);
    }
}