package org.edx.mobile.http;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import org.edx.mobile.BuildConfig;
import org.edx.mobile.R;
import java.io.File;
import java.net.HttpCookie;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import okhttp3.Cache;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class OkHttpUtil {
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
private static final int cacheSize = 10 * 1024 * 1024; // 10 MiB
public static OkHttpClient getClient(@NonNull Context context) {
return getClient(context, false, false);
}
public static OkHttpClient getOAuthBasedClient(@NonNull Context context) {
return getClient(context, true, false);
}
public static OkHttpClient getOAuthBasedClientWithOfflineCache(@NonNull Context context) {
return getClient(context, true, true);
}
private static OkHttpClient getClient(@NonNull Context context,
boolean isOAuthBased, boolean usesOfflineCache) {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
List<Interceptor> interceptors = builder.interceptors();
if (usesOfflineCache) {
final File cacheDirectory = new File(context.getFilesDir(), "http-cache");
if (!cacheDirectory.exists()) {
cacheDirectory.mkdirs();
}
final Cache cache = new Cache(cacheDirectory, cacheSize);
builder.cache(cache);
interceptors.add(new OfflineRequestInterceptor(context));
}
interceptors.add(new JsonMergePatchInterceptor());
interceptors.add(new UserAgentInterceptor(
System.getProperty("http.agent") + " " +
context.getString(R.string.app_name) + "/" +
BuildConfig.APPLICATION_ID + "/" +
BuildConfig.VERSION_NAME));
if (isOAuthBased) {
interceptors.add(new OauthHeaderRequestInterceptor(context));
}
interceptors.add(new NewVersionBroadcastInterceptor());
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
interceptors.add(loggingInterceptor);
}
builder.authenticator(new OauthRefreshTokenAuthenticator(context));
return builder.build();
}
/**
* get cookie for request. [GET or POST]
*/
public static List<HttpCookie> getCookies(Context context, String url, boolean isGet)
throws Exception {
final List<HttpCookie> cookies = new ArrayList<>();
OkHttpClient.Builder oauthBasedClientBuilder = getOAuthBasedClient(context).newBuilder();
oauthBasedClientBuilder.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> newCookies) {
for (Cookie cookie : newCookies) {
cookies.addAll(HttpCookie.parse(cookie.toString()));
}
}
@Override
public List<okhttp3.Cookie> loadForRequest(HttpUrl url) {
return null;
}
});
OkHttpClient oauthBasedClient = oauthBasedClientBuilder.build();
Request.Builder builder = new Request.Builder();
if (!isGet) {
RequestBody body = RequestBody.create(JSON, "");
builder.post(body);
}
Request request = builder.url(url).build();
Response response = oauthBasedClient.newCall(request).execute();
return cookies;
}
/**
* Returns GET url with appended parameters.
*
* @param url
* @param params
* @return
*/
public static String toGetUrl(String url, Bundle params) {
if (params != null) {
if (!url.endsWith("?")) {
url = url + "?";
}
for (String key : params.keySet()) {
url = url + key + "=" + params.getString(key) + "&";
}
}
return url;
}
//http://sangupta.com/tech/convert-between-java-servlet-and-apache.html
@Deprecated // Deprecated because this uses org.apache.http, which is itself deprecated
public static HttpCookie servletCookieFromApacheCookie(
org.apache.http.cookie.Cookie apacheCookie) {
if (apacheCookie == null) {
return null;
}
String name = apacheCookie.getName();
String value = apacheCookie.getValue();
HttpCookie cookie = new HttpCookie(name, value);
value = apacheCookie.getDomain();
if (value != null) {
cookie.setDomain(value);
}
value = apacheCookie.getPath();
if (value != null) {
cookie.setPath(value);
}
cookie.setSecure(apacheCookie.isSecure());
value = apacheCookie.getComment();
if (value != null) {
cookie.setComment(value);
}
// version
cookie.setVersion(apacheCookie.getVersion());
// From the Apache source code, maxAge is converted to expiry date using the following formula
// if (maxAge >= 0) {
// setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L));
// }
// Reverse this to get the actual max age
Date expiryDate = apacheCookie.getExpiryDate();
if (expiryDate != null) {
long maxAge = (expiryDate.getTime() - System.currentTimeMillis()) / 1000;
// we have to lower down, no other option
cookie.setMaxAge((int) maxAge);
}
// return the servlet cookie
return cookie;
}
public static enum REQUEST_CACHE_TYPE {IGNORE_CACHE, PREFER_CACHE, ONLY_CACHE}
}