package org.edx.mobile.http; import android.content.Context; import android.net.http.AndroidHttpClient; import android.os.Bundle; import com.google.inject.Inject; import com.google.inject.Singleton; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.protocol.ClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.edx.mobile.BuildConfig; import org.edx.mobile.R; import org.edx.mobile.logger.Logger; import org.edx.mobile.util.IOUtils; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.net.HttpCookie; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @Singleton @Deprecated // Deprecated because this uses org.apache.http, which is itself deprecated public class HttpManager { protected final Logger logger = new Logger(getClass().getName()); Context context; /** * Executes a GET request to given URL with given parameters. * * @param urlWithAppendedParams * @param headers * @return * @throws ParseException * @throws ClientProtocolException * @throws IOException */ @Inject public HttpManager(Context context) { this.context = context; } public HttpResult get(String urlWithAppendedParams, Bundle headers) throws ParseException, ClientProtocolException, IOException { final DefaultHttpClient client = newClient(); HttpGet get = new HttpGet(urlWithAppendedParams); AndroidHttpClient.modifyRequestToAcceptGzipResponse(get); // allow redirects HttpClientParams.setRedirecting(client.getParams(), true); HttpClientParams.setRedirecting(get.getParams(), true); // set request headers if (headers != null) { for (String key : headers.keySet()) { logger.debug(key + ": " + headers.getString(key)); get.setHeader(key, headers.getString(key)); } } HttpResponse response = client.execute(get); logger.debug("StatusCode for get request= " + response.getStatusLine().getStatusCode()); InputStream inputStream = AndroidHttpClient .getUngzippedContent(response.getEntity()); String strRes = IOUtils.toString(inputStream, Charset.defaultCharset()); // String response = // EntityUtils.toString(client.execute(get).getEntity(), "UTF-8"); client.getConnectionManager().shutdown(); HttpResult result = new HttpResult(); result.body = strRes; result.statusCode = response.getStatusLine().getStatusCode(); return result; } /** * Executes a POST request to given URL with given parameters. * Returns "cookie" in a JSON object if response is HTTP 204 NO CONTENT. * Returns "error=401" in JSON format if response code is 401. * @param url * @param params * @param headers * @return * @throws ParseException * @throws ClientProtocolException * @throws IOException */ public String post(String url, Bundle params, Bundle headers) throws ParseException, ClientProtocolException, IOException { final DefaultHttpClient client = newClient(); HttpPost post = new HttpPost(url); AndroidHttpClient.modifyRequestToAcceptGzipResponse(post); // set request headers if (headers != null) { for (String key : headers.keySet()) { post.addHeader(key, headers.getString(key)); } } if (params != null) { List<NameValuePair> pairs = new ArrayList<NameValuePair>(); for (String key : params.keySet()) { pairs.add(new BasicNameValuePair(key, params.getString(key))); } post.setEntity(new UrlEncodedFormEntity(pairs)); } HttpResponse response = client.execute(post); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.NO_CONTENT) { // that means response has "NO CONTENTS" // so return empty string // this is SUCCESS response for login by google/FB account logger.debug("HTTP 204 NO CONTENT"); if(response.containsHeader("Set-Cookie")){ Header header = response.getFirstHeader("Set-Cookie"); JSONObject json = new JSONObject(); try { json.put("cookie", header.getValue()); } catch (JSONException e) { logger.error(e); } // end connection and return client.getConnectionManager().shutdown(); return json.toString(); } } else if (statusCode == HttpStatus.UNAUTHORIZED) { // for google/FB login, this means google/FB account is not associated with edX logger.debug("Response of HTTP 401"); JSONObject json = new JSONObject(); try { json.put("error", "401"); } catch (JSONException e) { logger.error(e); } // end connection and return client.getConnectionManager().shutdown(); return json.toString(); } InputStream inputStream = AndroidHttpClient .getUngzippedContent(response.getEntity()); String strRes = IOUtils.toString(inputStream, Charset.defaultCharset()); client.getConnectionManager().shutdown(); return strRes; } /** * Performs a HTTP POST with given postBody and headers. * @param url * @param postBody * @param headers * @return * @throws ParseException * @throws ClientProtocolException * @throws IOException */ public String post(String url, String postBody, Bundle headers) throws ParseException, ClientProtocolException, IOException { // this is POST, so isPathRequest=false return post(url, postBody, headers, false); } /** * Performs a HTTP POST or PATCH request with given postBody and headers. * @param url * @param postBody * @param headers * @param isPatchRequest - If true, then performs PATCH request, POST otherwise. * @return * @throws ParseException * @throws ClientProtocolException * @throws IOException */ public String post(String url, String postBody, Bundle headers, boolean isPatchRequest) throws ParseException, ClientProtocolException, IOException { final DefaultHttpClient client = newClient(); HttpPost post = null; if (isPatchRequest) { post = new HttpPatch(url); } else { post = new HttpPost(url); } AndroidHttpClient.modifyRequestToAcceptGzipResponse(post); // set request headers if (headers != null) { for (String key : headers.keySet()) { post.addHeader(key, headers.getString(key)); } } StringEntity se = new StringEntity(postBody); se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); post.setEntity(se); HttpResponse response = client.execute(post); int statusCode = response.getStatusLine().getStatusCode(); //make this change to handle it consistent with iOS app if (statusCode != HttpStatus.OK ){ // Enroll endpoint may return 404 and 400 errors logger.debug("Response of HTTP " + statusCode); JSONObject json = new JSONObject(); try { json.put("error", String.valueOf(statusCode)); } catch (JSONException e) { logger.error(e); } // end connection and return client.getConnectionManager().shutdown(); return json.toString(); } InputStream inputStream = AndroidHttpClient .getUngzippedContent(response.getEntity()); String strRes = IOUtils.toString(inputStream, Charset.defaultCharset()); client.getConnectionManager().shutdown(); return strRes; } /** * 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; } public List<HttpCookie> getCookies(String url, Bundle headers, boolean isGet) throws ParseException, ClientProtocolException, IOException { final DefaultHttpClient client = newClient(); CookieStore cookieStore = new BasicCookieStore(); HttpContext localContext = new BasicHttpContext(); // Bind custom cookie store to the local context localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); HttpRequestBase get = isGet ? new HttpGet(url) : new HttpPost(url); // set request headers if (headers != null) { for (String key : headers.keySet()) { get.addHeader(key, headers.getString(key)); } } // Pass local context as a parameter try { client.execute(get, localContext); }catch (Exception ex){ logger.error(ex); } client.getConnectionManager().shutdown(); List<HttpCookie> cookieList = new ArrayList<>(); for(Cookie cookie : cookieStore.getCookies()){ HttpCookie copy = OkHttpUtil.servletCookieFromApacheCookie(cookie); if( copy != null ){ cookieList.add(copy); } } return cookieList; } public static class HttpResult { public String body; public int statusCode; } private DefaultHttpClient newClient() { DefaultHttpClient client = new DefaultHttpClient(); client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent") + " " + context.getString(R.string.app_name) + "/" + BuildConfig.APPLICATION_ID + "/" + BuildConfig.VERSION_NAME); return client; } }