diff options
author | Andrew Dolgov <[email protected]> | 2012-09-18 13:08:57 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2012-09-18 13:08:57 +0400 |
commit | 94b4aff15f4b7fe2b1a3380ac72e7637f9a7966a (patch) | |
tree | e31522b4b0b801b5a18ada36f527ecf7bf3909b5 /src/org | |
parent | 201dbfff770a0e1bbf16962603e0d4f3c18d5b79 (diff) |
switch to HttpURLConnection (which should enable SNI on recent android
versions)
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/fox/ttrss/ApiRequest.java | 171 | ||||
-rw-r--r-- | src/org/fox/ttrss/FeedsActivity.java | 3 | ||||
-rw-r--r-- | src/org/fox/ttrss/FeedsFragment.java | 111 | ||||
-rw-r--r-- | src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java | 2 | ||||
-rw-r--r-- | src/org/fox/ttrss/util/Base64.java | 582 | ||||
-rw-r--r-- | src/org/fox/ttrss/util/Base64DecoderException.java | 32 | ||||
-rw-r--r-- | src/org/fox/ttrss/util/EasySSLSocketFactory.java | 120 | ||||
-rw-r--r-- | src/org/fox/ttrss/util/EasyX509TrustManager.java | 26 |
8 files changed, 170 insertions, 877 deletions
diff --git a/src/org/fox/ttrss/ApiRequest.java b/src/org/fox/ttrss/ApiRequest.java index d067e394..ee510987 100644 --- a/src/org/fox/ttrss/ApiRequest.java +++ b/src/org/fox/ttrss/ApiRequest.java @@ -2,31 +2,27 @@ package org.fox.ttrss; import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
-import java.net.MalformedURLException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
import java.net.URL;
+import java.security.cert.CertificateException;
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.util.EasySSLSocketFactory;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import java.security.cert.X509Certificate;
import android.content.Context;
import android.content.SharedPreferences;
-import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
+import android.os.Build;
import android.preference.PreferenceManager;
+import android.util.Base64;
import android.util.Log;
import com.google.gson.Gson;
@@ -109,73 +105,61 @@ public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonE Gson gson = new Gson();
String requestStr = gson.toJson(new HashMap<String,String>(params[0]));
+ byte[] postData = null;
+
+ try {
+ postData = requestStr.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ m_lastError = ApiError.OTHER_ERROR;
+ e.printStackTrace();
+ return null;
+ }
+
+ disableConnectionReuseIfNecessary();
if (m_transportDebugging) Log.d(TAG, ">>> (" + requestStr + ") " + m_api);
- AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS"); + if (m_trustAny) trustAllHosts();
+
+ URL url;
- 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; - + url = new URL(m_api + "/api/");
+ } catch (Exception e) {
+ m_lastError = ApiError.INVALID_URL;
+ e.printStackTrace();
+ return null;
+ }
+
+ try {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
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); + conn.setRequestProperty("Authorization", "Basic " +
+ Base64.encode((httpLogin + ":" + httpPassword).getBytes("UTF-8"), Base64.NO_WRAP));
}
- httpPost.setEntity(new StringEntity(requestStr, "utf-8"));
- HttpResponse execute = client.execute(httpPost, context); -
- m_httpStatusCode = execute.getStatusLine().getStatusCode();
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setUseCaches(false);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Length", Integer.toString(postData.length));
+
+ OutputStream out = conn.getOutputStream();
+ out.write(postData);
+ out.close();
+
+ m_httpStatusCode = conn.getResponseCode();
- switch (m_httpStatusCode) {
+ switch (m_httpStatusCode) {
case 200:
- InputStream content = execute.getEntity().getContent();
-
BufferedReader buffer = new BufferedReader(
- new InputStreamReader(content), 8192);
+ new InputStreamReader(conn.getInputStream()), 8192);
String s = "";
String response = "";
@@ -193,7 +177,7 @@ public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonE m_apiStatusCode = resultObj.get("status").getAsInt();
- client.close();
+ conn.disconnect();
switch (m_apiStatusCode) {
case API_STATUS_OK:
@@ -233,9 +217,9 @@ public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonE m_lastError = ApiError.HTTP_OTHER_ERROR;
break;
}
-
- client.close();
- return null;
+
+ conn.disconnect();
+ return null;
} catch (javax.net.ssl.SSLPeerUnverifiedException e) {
m_lastError = ApiError.SSL_REJECTED;
e.printStackTrace();
@@ -250,7 +234,50 @@ public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonE e.printStackTrace();
}
- client.close();
return null;
}
+
+ private static void trustAllHosts() {
+ X509TrustManager easyTrustManager = new X509TrustManager() {
+
+ public void checkClientTrusted(
+ X509Certificate[] chain,
+ String authType) throws CertificateException {
+ // Oh, I am easy!
+ }
+
+ public void checkServerTrusted(
+ X509Certificate[] chain,
+ String authType) throws CertificateException {
+ // Oh, I am easy!
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ };
+
+ // Create a trust manager that does not validate certificate chains
+ TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};
+
+ // Install the all-trusting trust manager
+ try {
+ SSLContext sc = SSLContext.getInstance("TLS");
+
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void disableConnectionReuseIfNecessary() {
+ // HTTP connection reuse which was buggy pre-froyo
+ if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
+ System.setProperty("http.keepAlive", "false");
+ }
+ }
}
diff --git a/src/org/fox/ttrss/FeedsActivity.java b/src/org/fox/ttrss/FeedsActivity.java index 302ce7a9..0d40da4a 100644 --- a/src/org/fox/ttrss/FeedsActivity.java +++ b/src/org/fox/ttrss/FeedsActivity.java @@ -6,6 +6,7 @@ import org.fox.ttrss.types.Article; import org.fox.ttrss.types.ArticleList;
import org.fox.ttrss.types.Feed;
import org.fox.ttrss.types.FeedCategory;
+import org.fox.ttrss.util.AppRater;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -97,6 +98,8 @@ public class FeedsActivity extends OnlineActivity implements HeadlinesEventListe }
ft.commit();
+
+ AppRater.appLaunched(this);
}
}
}
diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java index 2e4a8433..7b307f84 100644 --- a/src/org/fox/ttrss/FeedsFragment.java +++ b/src/org/fox/ttrss/FeedsFragment.java @@ -5,29 +5,24 @@ import java.io.File; import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Type;
-import java.net.MalformedURLException;
+import java.net.HttpURLConnection;
import java.net.URL;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
-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.HttpGet;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
import org.fox.ttrss.types.Feed;
import org.fox.ttrss.types.FeedCategory;
import org.fox.ttrss.types.FeedList;
-import org.fox.ttrss.util.EasySSLSocketFactory;
import android.app.Activity;
import android.content.Context;
@@ -37,10 +32,12 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
+import android.util.Base64;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -541,46 +538,72 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh return null;
}
+ private void trustAllHosts() {
+ X509TrustManager easyTrustManager = new X509TrustManager() {
+
+ public void checkClientTrusted(
+ X509Certificate[] chain,
+ String authType) throws CertificateException {
+ // Oh, I am easy!
+ }
+
+ public void checkServerTrusted(
+ X509Certificate[] chain,
+ String authType) throws CertificateException {
+ // Oh, I am easy!
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ };
+
+ // Create a trust manager that does not validate certificate chains
+ TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};
+
+ // Install the all-trusting trust manager
+ try {
+ SSLContext sc = SSLContext.getInstance("TLS");
+
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void disableConnectionReuseIfNecessary() {
+ // HTTP connection reuse which was buggy pre-froyo
+ if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
+ System.setProperty("http.keepAlive", "false");
+ }
+ }
+
protected void downloadFile(String fetchUrl, String outputFile) {
AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS"); + disableConnectionReuseIfNecessary();
+
if (m_prefs.getBoolean("ssl_trust_any", false)) {
- client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", new EasySSLSocketFactory(), 443)); + trustAllHosts(); }
- HttpGet httpGet = new HttpGet(fetchUrl);
- HttpContext context = null; + try {
+ URL url = new URL(fetchUrl);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- String httpLogin = m_prefs.getString("http_login", "");
- String httpPassword = m_prefs.getString("http_password", "");
-
- if (httpLogin.length() > 0) {
-
- URL targetUrl;
- try {
- targetUrl = new URL(fetchUrl);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- client.close();
- return;
- }
-
- HttpHost targetHost = new HttpHost(targetUrl.getHost(), targetUrl.getPort(), targetUrl.getProtocol());
- CredentialsProvider cp = new BasicCredentialsProvider(); - context = new BasicHttpContext(); + String httpLogin = m_prefs.getString("http_login", "");
+ String httpPassword = m_prefs.getString("http_password", "");
- cp.setCredentials( - new AuthScope(targetHost.getHostName(), targetHost.getPort()),
- new UsernamePasswordCredentials(httpLogin, httpPassword));
- - context.setAttribute(ClientContext.CREDS_PROVIDER, cp); - }
-
+ if (httpLogin.length() > 0) {
+ conn.setRequestProperty("Authorization", "Basic " +
+ Base64.encode((httpLogin + ":" + httpPassword).getBytes("UTF-8"), Base64.NO_WRAP));
+ }
- try {
- HttpResponse execute = client.execute(httpGet, context); -
- InputStream content = execute.getEntity().getContent();
+ InputStream content = conn.getInputStream();
BufferedInputStream is = new BufferedInputStream(content, 1024);
FileOutputStream fos = new FileOutputStream(outputFile);
diff --git a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java index 769a3795..0a4c416b 100644 --- a/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ b/src/org/fox/ttrss/offline/OfflineHeadlinesFragment.java @@ -467,7 +467,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis if (feedTitle.length() > 20)
feedTitle = feedTitle.substring(0, 20) + "...";
- if (feedTitle != null) {
+ if (feedTitle.length() > 0) {
ft.setText(feedTitle);
} else {
ft.setVisibility(View.GONE);
diff --git a/src/org/fox/ttrss/util/Base64.java b/src/org/fox/ttrss/util/Base64.java deleted file mode 100644 index 5c8136db..00000000 --- a/src/org/fox/ttrss/util/Base64.java +++ /dev/null @@ -1,582 +0,0 @@ -// Portions copyright 2002, Google, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package org.fox.ttrss.util; - -// This code was converted from code at http://iharder.sourceforge.net/base64/ -// Lots of extraneous features were removed. -/* The original code said: - * <p> - * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit - * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a> - * periodically to check for updates or to contribute improvements. - * </p> - * - * @author Robert Harder - * @author [email protected] - * @version 1.3 - */ - -/** - * Base64 converter class. This code is not a complete MIME encoder; it simply - * converts binary data to base64 data and back. - * - * <p> - * Note {@link CharBase64} is a GWT-compatible implementation of this class. - */ -public class Base64 { - /** Specify encoding (value is {@code true}). */ - public final static boolean ENCODE = true; - - /** Specify decoding (value is {@code false}). */ - public final static boolean DECODE = false; - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte) '='; - - /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte) '\n'; - - /** - * The 64 valid Base64 values. - */ - private final static byte[] ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', - (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', - (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', - (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', - (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', - (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', - (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' }; - - /** - * The 64 valid web safe Base64 values. - */ - private final static byte[] WEBSAFE_ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', - (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', - (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', - (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', - (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', - (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', - (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_' }; - - /** - * Translates a Base64 value to either its 6-bit reconstruction value or a - * negative number indicating some other meaning. - **/ - private final static byte[] DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal - // 0 - // - - // 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - - // 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9, -9, -9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through - // 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' - // through 'Z' - -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' - // through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' - // through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - /* - * ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 - */ - }; - - /** The web safe decodabet */ - private final static byte[] WEBSAFE_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal - // 0 - // - - // 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - - // 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44 - 62, // Dash '-' sign at decimal 45 - -9, -9, // Decimal 46-47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through - // 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' - // through 'Z' - -9, -9, -9, -9, // Decimal 91-94 - 63, // Underscore '_' at decimal 95 - -9, // Decimal 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' - // through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' - // through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - /* - * ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - * -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 - */ - }; - - // Indicates white space in encoding - private final static byte WHITE_SPACE_ENC = -5; - // Indicates equals sign in encoding - private final static byte EQUALS_SIGN_ENC = -1; - - /** Defeats instantiation. */ - private Base64() { - } - - /* ******** E N C O D I N G M E T H O D S ******** */ - - /** - * Encodes up to three bytes of the array <var>source</var> and writes the - * resulting four Base64 bytes to <var>destination</var>. The source and - * destination arrays can be manipulated anywhere along their length by - * specifying <var>srcOffset</var> and <var>destOffset</var>. This method - * does not check to make sure your arrays are large enough to accommodate - * <var>srcOffset</var> + 3 for the <var>source</var> array or - * <var>destOffset</var> + 4 for the <var>destination</var> array. The - * actual number of significant bytes in your array is given by - * <var>numSigBytes</var>. - * - * @param source - * the array to convert - * @param srcOffset - * the index where conversion begins - * @param numSigBytes - * the number of significant bytes in your array - * @param destination - * the array to hold the conversion - * @param destOffset - * the index where output will be put - * @param alphabet - * is the encoding alphabet - * @return the <var>destination</var> array - * @since 1.3 - */ - private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) { - // 1 2 3 - // 01234567890123456789012345678901 Bit position - // --------000000001111111122222222 Array position from threeBytes - // --------| || || || | Six bit groups to index alphabet - // >>18 >>12 >> 6 >> 0 Right shift necessary - // 0x3f 0x3f 0x3f Additional AND - - // Create buffer with zero-padding if there are only one or two - // significant bytes passed in the array. - // We have to shift left 24 in order to flush out the 1's that appear - // when Java treats a value as negative that is cast from a byte to an - // int. - int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) - | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) - | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); - - switch (numSigBytes) { - case 3: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - destination[destOffset + 3] = alphabet[(inBuff) & 0x3f]; - return destination; - case 2: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - destination[destOffset + 3] = EQUALS_SIGN; - return destination; - case 1: - destination[destOffset] = alphabet[(inBuff >>> 18)]; - destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - destination[destOffset + 2] = EQUALS_SIGN; - destination[destOffset + 3] = EQUALS_SIGN; - return destination; - default: - return destination; - } // end switch - } // end encode3to4 - - /** - * Encodes a byte array into Base64 notation. Equivalent to calling {@code - * encodeBytes(source, 0, source.length)} - * - * @param source - * The data to convert - * @since 1.4 - */ - public static String encode(byte[] source) { - return encode(source, 0, source.length, ALPHABET, true); - } - - /** - * Encodes a byte array into web safe Base64 notation. - * - * @param source - * The data to convert - * @param doPadding - * is {@code true} to pad result with '=' chars if it does not - * fall on 3 byte boundaries - */ - public static String encodeWebSafe(byte[] source, boolean doPadding) { - return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding); - } - - /** - * Encodes a byte array into Base64 notation. - * - * @param source - * the data to convert - * @param off - * offset in array where conversion should begin - * @param len - * length of data to convert - * @param alphabet - * the encoding alphabet - * @param doPadding - * is {@code true} to pad result with '=' chars if it does not - * fall on 3 byte boundaries - * @since 1.4 - */ - public static String encode(byte[] source, int off, int len, byte[] alphabet, boolean doPadding) { - byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE); - int outLen = outBuff.length; - - // If doPadding is false, set length to truncate '=' - // padding characters - while (doPadding == false && outLen > 0) { - if (outBuff[outLen - 1] != '=') { - break; - } - outLen -= 1; - } - - return new String(outBuff, 0, outLen); - } - - /** - * Encodes a byte array into Base64 notation. - * - * @param source - * the data to convert - * @param off - * offset in array where conversion should begin - * @param len - * length of data to convert - * @param alphabet - * is the encoding alphabet - * @param maxLineLength - * maximum length of one line. - * @return the BASE64-encoded byte array - */ - public static byte[] encode(byte[] source, int off, int len, byte[] alphabet, int maxLineLength) { - int lenDiv3 = (len + 2) / 3; // ceil(len / 3) - int len43 = lenDiv3 * 4; - byte[] outBuff = new byte[len43 // Main 4:3 - + (len43 / maxLineLength)]; // New lines - - int d = 0; - int e = 0; - int len2 = len - 2; - int lineLength = 0; - for (; d < len2; d += 3, e += 4) { - - // The following block of code is the same as - // encode3to4( source, d + off, 3, outBuff, e, alphabet ); - // but inlined for faster encoding (~20% improvement) - int inBuff = ((source[d + off] << 24) >>> 8) | ((source[d + 1 + off] << 24) >>> 16) | ((source[d + 2 + off] << 24) >>> 24); - outBuff[e] = alphabet[(inBuff >>> 18)]; - outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f]; - outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f]; - outBuff[e + 3] = alphabet[(inBuff) & 0x3f]; - - lineLength += 4; - if (lineLength == maxLineLength) { - outBuff[e + 4] = NEW_LINE; - e++; - lineLength = 0; - } // end if: end of line - } // end for: each piece of array - - if (d < len) { - encode3to4(source, d + off, len - d, outBuff, e, alphabet); - - lineLength += 4; - if (lineLength == maxLineLength) { - // Add a last newline - outBuff[e + 4] = NEW_LINE; - e++; - } - e += 4; - } - - assert (e == outBuff.length); - return outBuff; - } - - /* ******** D E C O D I N G M E T H O D S ******** */ - - /** - * Decodes four bytes from array <var>source</var> and writes the resulting - * bytes (up to three of them) to <var>destination</var>. The source and - * destination arrays can be manipulated anywhere along their length by - * specifying <var>srcOffset</var> and <var>destOffset</var>. This method - * does not check to make sure your arrays are large enough to accommodate - * <var>srcOffset</var> + 4 for the <var>source</var> array or - * <var>destOffset</var> + 3 for the <var>destination</var> array. This - * method returns the actual number of bytes that were converted from the - * Base64 encoding. - * - * - * @param source - * the array to convert - * @param srcOffset - * the index where conversion begins - * @param destination - * the array to hold the conversion - * @param destOffset - * the index where output will be put - * @param decodabet - * the decodabet for decoding Base64 content - * @return the number of decoded bytes converted - * @since 1.3 - */ - private static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset, byte[] decodabet) { - // Example: Dk== - if (source[srcOffset + 2] == EQUALS_SIGN) { - int outBuff = ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12); - - destination[destOffset] = (byte) (outBuff >>> 16); - return 1; - } else if (source[srcOffset + 3] == EQUALS_SIGN) { - // Example: DkL= - int outBuff = ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) - | ((decodabet[source[srcOffset + 2]] << 24) >>> 18); - - destination[destOffset] = (byte) (outBuff >>> 16); - destination[destOffset + 1] = (byte) (outBuff >>> 8); - return 2; - } else { - // Example: DkLE - int outBuff = ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) - | ((decodabet[source[srcOffset + 2]] << 24) >>> 18) | ((decodabet[source[srcOffset + 3]] << 24) >>> 24); - - destination[destOffset] = (byte) (outBuff >> 16); - destination[destOffset + 1] = (byte) (outBuff >> 8); - destination[destOffset + 2] = (byte) (outBuff); - return 3; - } - } // end decodeToBytes - - /** - * Decodes data from Base64 notation. - * - * @param s - * the string to decode (decoded in default encoding) - * @return the decoded data - * @since 1.4 - */ - public static byte[] decode(String s) throws Base64DecoderException { - byte[] bytes = s.getBytes(); - return decode(bytes, 0, bytes.length); - } - - /** - * Decodes data from web safe Base64 notation. Web safe encoding uses '-' - * instead of '+', '_' instead of '/' - * - * @param s - * the string to decode (decoded in default encoding) - * @return the decoded data - */ - public static byte[] decodeWebSafe(String s) throws Base64DecoderException { - byte[] bytes = s.getBytes(); - return decodeWebSafe(bytes, 0, bytes.length); - } - - /** - * Decodes Base64 content in byte array format and returns the decoded byte - * array. - * - * @param source - * The Base64 encoded data - * @return decoded data - * @since 1.3 - * @throws Base64DecoderException - */ - public static byte[] decode(byte[] source) throws Base64DecoderException { - return decode(source, 0, source.length); - } - - /** - * Decodes web safe Base64 content in byte array format and returns the - * decoded data. Web safe encoding uses '-' instead of '+', '_' instead of - * '/' - * - * @param source - * the string to decode (decoded in default encoding) - * @return the decoded data - */ - public static byte[] decodeWebSafe(byte[] source) throws Base64DecoderException { - return decodeWebSafe(source, 0, source.length); - } - - /** - * Decodes Base64 content in byte array format and returns the decoded byte - * array. - * - * @param source - * the Base64 encoded data - * @param off - * the offset of where to begin decoding - * @param len - * the length of characters to decode - * @return decoded data - * @since 1.3 - * @throws Base64DecoderException - */ - public static byte[] decode(byte[] source, int off, int len) throws Base64DecoderException { - return decode(source, off, len, DECODABET); - } - - /** - * Decodes web safe Base64 content in byte array format and returns the - * decoded byte array. Web safe encoding uses '-' instead of '+', '_' - * instead of '/' - * - * @param source - * the Base64 encoded data - * @param off - * the offset of where to begin decoding - * @param len - * the length of characters to decode - * @return decoded data - */ - public static byte[] decodeWebSafe(byte[] source, int off, int len) throws Base64DecoderException { - return decode(source, off, len, WEBSAFE_DECODABET); - } - - /** - * Decodes Base64 content using the supplied decodabet and returns the - * decoded byte array. - * - * @param source - * the Base64 encoded data - * @param off - * the offset of where to begin decoding - * @param len - * the length of characters to decode - * @param decodabet - * the decodabet for decoding Base64 content - * @return decoded data - */ - public static byte[] decode(byte[] source, int off, int len, byte[] decodabet) throws Base64DecoderException { - int len34 = len * 3 / 4; - byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output - int outBuffPosn = 0; - - byte[] b4 = new byte[4]; - int b4Posn = 0; - int i = 0; - byte sbiCrop = 0; - byte sbiDecode = 0; - for (i = 0; i < len; i++) { - sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven - // bits - sbiDecode = decodabet[sbiCrop]; - - if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or - // better - if (sbiDecode >= EQUALS_SIGN_ENC) { - // An equals sign (for padding) must not occur at position 0 - // or 1 - // and must be the last byte[s] in the encoded value - if (sbiCrop == EQUALS_SIGN) { - int bytesLeft = len - i; - byte lastByte = (byte) (source[len - 1 + off] & 0x7f); - if (b4Posn == 0 || b4Posn == 1) { - throw new Base64DecoderException("invalid padding byte '=' at byte offset " + i); - } else if ((b4Posn == 3 && bytesLeft > 2) || (b4Posn == 4 && bytesLeft > 1)) { - throw new Base64DecoderException("padding byte '=' falsely signals end of encoded value " + "at offset " + i); - } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) { - throw new Base64DecoderException("encoded value has invalid trailing byte"); - } - break; - } - - b4[b4Posn++] = sbiCrop; - if (b4Posn == 4) { - outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); - b4Posn = 0; - } - } - } else { - throw new Base64DecoderException("Bad Base64 input character at " + i + ": " + source[i + off] + "(decimal)"); - } - } - - // Because web safe encoding allows non padding base64 encodes, we - // need to pad the rest of the b4 buffer with equal signs when - // b4Posn != 0. There can be at most 2 equal signs at the end of - // four characters, so the b4 buffer must have two or three - // characters. This also catches the case where the input is - // padded with EQUALS_SIGN - if (b4Posn != 0) { - if (b4Posn == 1) { - // Ensure you have set your public key - throw new Base64DecoderException("single trailing character at offset " + (len - 1)); - } - b4[b4Posn++] = EQUALS_SIGN; - outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); - } - - byte[] out = new byte[outBuffPosn]; - System.arraycopy(outBuff, 0, out, 0, outBuffPosn); - return out; - } -} diff --git a/src/org/fox/ttrss/util/Base64DecoderException.java b/src/org/fox/ttrss/util/Base64DecoderException.java deleted file mode 100644 index 7b7be229..00000000 --- a/src/org/fox/ttrss/util/Base64DecoderException.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2002, Google, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package org.fox.ttrss.util;; - -/** - * Exception thrown when encountering an invalid Base64 input character. - * - * @author nelson - */ -public class Base64DecoderException extends Exception { - public Base64DecoderException() { - super(); - } - - public Base64DecoderException(String s) { - super(s); - } - - private static final long serialVersionUID = 1L; -} diff --git a/src/org/fox/ttrss/util/EasySSLSocketFactory.java b/src/org/fox/ttrss/util/EasySSLSocketFactory.java deleted file mode 100644 index f0c2d3ad..00000000 --- a/src/org/fox/ttrss/util/EasySSLSocketFactory.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.fox.ttrss.util;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.scheme.LayeredSocketFactory;
-import org.apache.http.conn.scheme.SocketFactory;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-
-public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory
-{
- private SSLContext sslcontext = null;
-
- private static SSLContext createEasySSLContext() throws IOException
- {
- try
- {
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, new TrustManager[] { new EasyX509TrustManager() }, null);
- return context;
- }
- catch (Exception e)
- {
- throw new IOException(e.getMessage());
- }
- }
-
- private SSLContext getSSLContext() throws IOException
- {
- if (this.sslcontext == null)
- {
- this.sslcontext = createEasySSLContext();
- }
- return this.sslcontext;
- }
-
- /**
- * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, java.lang.String, int,
- * java.net.InetAddress, int, org.apache.http.params.HttpParams)
- */
- public Socket connectSocket(Socket sock,
- String host,
- int port,
- InetAddress localAddress,
- int localPort,
- HttpParams params)
-
- throws IOException, UnknownHostException, ConnectTimeoutException
- {
- int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
- int soTimeout = HttpConnectionParams.getSoTimeout(params);
- InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
- SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
-
- if ((localAddress != null) || (localPort > 0))
- {
- // we need to bind explicitly
- if (localPort < 0)
- {
- localPort = 0; // indicates "any"
- }
- InetSocketAddress isa = new InetSocketAddress(localAddress, localPort);
- sslsock.bind(isa);
- }
-
- sslsock.connect(remoteAddress, connTimeout);
- sslsock.setSoTimeout(soTimeout);
- return sslsock;
- }
-
- /**
- * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
- */
- public Socket createSocket() throws IOException {
- return getSSLContext().getSocketFactory().createSocket();
- }
-
- /**
- * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
- */
- public boolean isSecure(Socket socket) throws IllegalArgumentException {
- return true;
- }
-
- /**
- * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, java.lang.String, int,
- * boolean)
- */
- public Socket createSocket(Socket socket,
- String host,
- int port,
- boolean autoClose) throws IOException,
- UnknownHostException
- {
- return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
- }
-
- // -------------------------------------------------------------------
- // javadoc in org.apache.http.conn.scheme.SocketFactory says :
- // Both Object.equals() and Object.hashCode() must be overridden
- // for the correct operation of some connection managers
- // -------------------------------------------------------------------
-
- public boolean equals(Object obj) {
- return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
- }
-
- public int hashCode() {
- return EasySSLSocketFactory.class.hashCode();
- }
-}
\ No newline at end of file diff --git a/src/org/fox/ttrss/util/EasyX509TrustManager.java b/src/org/fox/ttrss/util/EasyX509TrustManager.java deleted file mode 100644 index 5ffc19bb..00000000 --- a/src/org/fox/ttrss/util/EasyX509TrustManager.java +++ /dev/null @@ -1,26 +0,0 @@ -
-package org.fox.ttrss.util;
-
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.X509TrustManager;
-
-// http://stackoverflow.com/questions/6989116/httpget-not-working-due-to-not-trusted-server-certificate-but-it-works-with-ht
-
-public class EasyX509TrustManager implements X509TrustManager {
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException { }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException { }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
-
-}
|