From ced80be1aea975b59db5a0e6dd14acb054e7910e Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 16 Sep 2012 13:25:28 +0400 Subject: initial --- src/org/fox/ttrss/util/ApiRequest.java | 257 +++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 src/org/fox/ttrss/util/ApiRequest.java (limited to 'src/org/fox/ttrss/util/ApiRequest.java') diff --git a/src/org/fox/ttrss/util/ApiRequest.java b/src/org/fox/ttrss/util/ApiRequest.java new file mode 100644 index 00000000..56901393 --- /dev/null +++ b/src/org/fox/ttrss/util/ApiRequest.java @@ -0,0 +1,257 @@ +package org.fox.ttrss.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; + +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.fox.ttrss.R; +import org.fox.ttrss.R.string; + +import android.content.Context; +import android.content.SharedPreferences; +import android.net.http.AndroidHttpClient; +import android.os.AsyncTask; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class ApiRequest extends AsyncTask, Integer, JsonElement> { + private final String TAG = this.getClass().getSimpleName(); + + public enum ApiError { NO_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND, + HTTP_SERVER_ERROR, HTTP_OTHER_ERROR, SSL_REJECTED, PARSE_ERROR, IO_ERROR, OTHER_ERROR, API_DISABLED, API_UNKNOWN, LOGIN_FAILED, INVALID_URL, INCORRECT_USAGE }; + + public static final int API_STATUS_OK = 0; + public static final int API_STATUS_ERR = 1; + + private String m_api; + private boolean m_trustAny = false; + private boolean m_transportDebugging = false; + protected int m_httpStatusCode = 0; + protected int m_apiStatusCode = 0; + protected Context m_context; + private SharedPreferences m_prefs; + + protected ApiError m_lastError; + + public ApiRequest(Context context) { + m_context = context; + + m_prefs = PreferenceManager.getDefaultSharedPreferences(m_context); + + m_api = m_prefs.getString("ttrss_url", null).trim(); + m_trustAny = m_prefs.getBoolean("ssl_trust_any", false); + m_transportDebugging = m_prefs.getBoolean("transport_debugging", false); + m_lastError = ApiError.NO_ERROR; + + } + + protected int getErrorMessage() { + switch (m_lastError) { + case NO_ERROR: + return R.string.error_unknown; + case HTTP_UNAUTHORIZED: + return R.string.error_http_unauthorized; + case HTTP_FORBIDDEN: + return R.string.error_http_forbidden; + case HTTP_NOT_FOUND: + return R.string.error_http_not_found; + case HTTP_SERVER_ERROR: + return R.string.error_http_server_error; + case HTTP_OTHER_ERROR: + return R.string.error_http_other_error; + case SSL_REJECTED: + return R.string.error_ssl_rejected; + case PARSE_ERROR: + return R.string.error_parse_error; + case IO_ERROR: + return R.string.error_io_error; + case OTHER_ERROR: + return R.string.error_other_error; + case API_DISABLED: + return R.string.error_api_disabled; + case API_UNKNOWN: + return R.string.error_api_unknown; + case LOGIN_FAILED: + return R.string.error_login_failed; + case INVALID_URL: + return R.string.error_invalid_api_url; + case INCORRECT_USAGE: + return R.string.error_api_incorrect_usage; + default: + Log.d(TAG, "getErrorMessage: unknown error code=" + m_lastError); + return R.string.error_unknown; + } + } + + @Override + protected JsonElement doInBackground(HashMap... params) { + + Gson gson = new Gson(); + + String requestStr = gson.toJson(new HashMap(params[0])); + + if (m_transportDebugging) Log.d(TAG, ">>> (" + requestStr + ") " + m_api); + + AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS"); + + if (m_trustAny) { + client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", new EasySSLSocketFactory(), 443)); + } + + try { + + HttpPost httpPost; + + try { + httpPost = new HttpPost(m_api + "/api/"); + } catch (IllegalArgumentException e) { + m_lastError = ApiError.INVALID_URL; + e.printStackTrace(); + client.close(); + return null; + } catch (Exception e) { + m_lastError = ApiError.OTHER_ERROR; + e.printStackTrace(); + client.close(); + return null; + } + + HttpContext context = null; + + String httpLogin = m_prefs.getString("http_login", "").trim(); + String httpPassword = m_prefs.getString("http_password", "").trim(); + + if (httpLogin.length() > 0) { + if (m_transportDebugging) Log.d(TAG, "Using HTTP Basic authentication."); + + URL targetUrl; + try { + targetUrl = new URL(m_api); + } catch (MalformedURLException e) { + m_lastError = ApiError.INVALID_URL; + e.printStackTrace(); + client.close(); + return null; + } + + HttpHost targetHost = new HttpHost(targetUrl.getHost(), targetUrl.getPort(), targetUrl.getProtocol()); + CredentialsProvider cp = new BasicCredentialsProvider(); + context = new BasicHttpContext(); + + cp.setCredentials( + new AuthScope(targetHost.getHostName(), targetHost.getPort()), + new UsernamePasswordCredentials(httpLogin, httpPassword)); + + context.setAttribute(ClientContext.CREDS_PROVIDER, cp); + } + + httpPost.setEntity(new StringEntity(requestStr, "utf-8")); + HttpResponse execute = client.execute(httpPost, context); + + m_httpStatusCode = execute.getStatusLine().getStatusCode(); + + switch (m_httpStatusCode) { + case 200: + InputStream content = execute.getEntity().getContent(); + + BufferedReader buffer = new BufferedReader( + new InputStreamReader(content), 8192); + + String s = ""; + String response = ""; + + while ((s = buffer.readLine()) != null) { + response += s; + } + + if (m_transportDebugging) Log.d(TAG, "<<< " + response); + + JsonParser parser = new JsonParser(); + + JsonElement result = parser.parse(response); + JsonObject resultObj = result.getAsJsonObject(); + + m_apiStatusCode = resultObj.get("status").getAsInt(); + + client.close(); + + switch (m_apiStatusCode) { + case API_STATUS_OK: + return result.getAsJsonObject().get("content"); + case API_STATUS_ERR: + JsonObject contentObj = resultObj.get("content").getAsJsonObject(); + String error = contentObj.get("error").getAsString(); + + if (error.equals("LOGIN_ERROR")) { + m_lastError = ApiError.LOGIN_FAILED; + } else if (error.equals("API_DISABLED")) { + m_lastError = ApiError.API_DISABLED; + } else if (error.equals("NOT_LOGGED_IN")) { + m_lastError = ApiError.LOGIN_FAILED; + } else if (error.equals("INCORRECT_USAGE")) { + m_lastError = ApiError.INCORRECT_USAGE; + } else { + Log.d(TAG, "Unknown API error: " + error); + m_lastError = ApiError.API_UNKNOWN; + } + } + + return null; + case 401: + m_lastError = ApiError.HTTP_UNAUTHORIZED; + break; + case 403: + m_lastError = ApiError.HTTP_FORBIDDEN; + break; + case 404: + m_lastError = ApiError.HTTP_NOT_FOUND; + break; + case 500: + m_lastError = ApiError.HTTP_SERVER_ERROR; + break; + default: + m_lastError = ApiError.HTTP_OTHER_ERROR; + break; + } + + client.close(); + return null; + } catch (javax.net.ssl.SSLPeerUnverifiedException e) { + m_lastError = ApiError.SSL_REJECTED; + e.printStackTrace(); + } catch (IOException e) { + m_lastError = ApiError.IO_ERROR; + e.printStackTrace(); + } catch (com.google.gson.JsonSyntaxException e) { + m_lastError = ApiError.PARSE_ERROR; + e.printStackTrace(); + } catch (Exception e) { + m_lastError = ApiError.OTHER_ERROR; + e.printStackTrace(); + } + + client.close(); + return null; + } +} -- cgit v1.2.3-54-g00ecf