添加https支持
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -37,7 +37,7 @@
|
|||||||
<ConfirmationsSetting value="0" id="Add" />
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
@ -30,6 +30,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.PopupWindow;
|
import android.widget.PopupWindow;
|
||||||
import com.arialyy.aria.core.command.CmdFactory;
|
import com.arialyy.aria.core.command.CmdFactory;
|
||||||
|
import com.arialyy.aria.util.CAConfiguration;
|
||||||
import com.arialyy.aria.util.CheckUtil;
|
import com.arialyy.aria.util.CheckUtil;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import com.arialyy.aria.core.command.IDownloadCmd;
|
import com.arialyy.aria.core.command.IDownloadCmd;
|
||||||
@ -73,6 +74,24 @@ import java.util.Set;
|
|||||||
return getTarget(obj);
|
return getTarget(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置CA证书信息
|
||||||
|
*
|
||||||
|
* @param caAlias ca证书别名
|
||||||
|
* @param caPath assets 文件夹下的ca证书完整路径
|
||||||
|
*/
|
||||||
|
public void setCAInfo(String caAlias, String caPath) {
|
||||||
|
if (TextUtils.isEmpty(caAlias)) {
|
||||||
|
Log.e(TAG, "ca证书别名不能为null");
|
||||||
|
return;
|
||||||
|
} else if (TextUtils.isEmpty(caPath)) {
|
||||||
|
Log.e(TAG, "ca证书路径不能为null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CAConfiguration.CA_ALIAS = caAlias;
|
||||||
|
CAConfiguration.CA_PATH = caPath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下载列表
|
* 获取下载列表
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,9 @@ import android.content.Context;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import com.arialyy.aria.core.DownloadEntity;
|
import com.arialyy.aria.core.DownloadEntity;
|
||||||
|
import com.arialyy.aria.util.CAConfiguration;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
|
import com.arialyy.aria.util.SSLContextUtil;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -29,9 +31,13 @@ import java.net.HttpURLConnection;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.ProtocolException;
|
import java.net.ProtocolException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2015/8/25.
|
* Created by lyy on 2015/8/25.
|
||||||
@ -223,7 +229,7 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(mDownloadEntity.getDownloadUrl());
|
URL url = new URL(mDownloadEntity.getDownloadUrl());
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = handleConnection(url);
|
||||||
setConnectParam(conn);
|
setConnectParam(conn);
|
||||||
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
||||||
conn.setConnectTimeout(mConnectTimeOut * 4);
|
conn.setConnectTimeout(mConnectTimeOut * 4);
|
||||||
@ -263,6 +269,30 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理链接
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private HttpURLConnection handleConnection(URL url) throws IOException {
|
||||||
|
HttpURLConnection conn;
|
||||||
|
URLConnection urlConn = url.openConnection();
|
||||||
|
if (urlConn instanceof HttpsURLConnection) {
|
||||||
|
conn = (HttpsURLConnection) urlConn;
|
||||||
|
SSLContext sslContext =
|
||||||
|
SSLContextUtil.getSSLContext(CAConfiguration.CA_ALIAS, CAConfiguration.CA_ALIAS);
|
||||||
|
if (sslContext == null) {
|
||||||
|
sslContext = SSLContextUtil.getDefaultSLLContext();
|
||||||
|
}
|
||||||
|
SSLSocketFactory ssf = sslContext.getSocketFactory();
|
||||||
|
((HttpsURLConnection) conn).setSSLSocketFactory(ssf);
|
||||||
|
((HttpsURLConnection) conn).setHostnameVerifier(SSLContextUtil.HOSTNAME_VERIFIER);
|
||||||
|
} else {
|
||||||
|
conn = (HttpURLConnection) urlConn;
|
||||||
|
}
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理断点
|
* 处理断点
|
||||||
*/
|
*/
|
||||||
@ -413,7 +443,8 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
URL url = new URL(configEntity.downloadUrl);
|
URL url = new URL(configEntity.downloadUrl);
|
||||||
conn = (HttpURLConnection) url.openConnection();
|
//conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn = handleConnection(url);
|
||||||
if (isSupportBreakpoint) {
|
if (isSupportBreakpoint) {
|
||||||
Log.d(TAG, "线程_"
|
Log.d(TAG, "线程_"
|
||||||
+ configEntity.threadId
|
+ configEntity.threadId
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.arialyy.aria.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Aria.Lao on 2017/1/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CAConfiguration {
|
||||||
|
public static String CA_PATH, CA_ALIAS;
|
||||||
|
}
|
112
Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java
Normal file
112
Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package com.arialyy.aria.util;
|
||||||
|
|
||||||
|
import com.arialyy.aria.core.DownloadManager;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.UnrecoverableKeyException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Aria.Lao on 2017/1/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SSLContextUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 颁发服务器证书的 CA 未知
|
||||||
|
*
|
||||||
|
* @param caAlias CA证书别名
|
||||||
|
* @param caPath 保存在assets目录下的CA证书完整路径
|
||||||
|
*/
|
||||||
|
public static SSLContext getSSLContext(String caAlias, String caPath) {
|
||||||
|
// Load CAs from an InputStream
|
||||||
|
// (could be from a resource or ByteArrayInputStream or ...)
|
||||||
|
CertificateFactory cf = null;
|
||||||
|
try {
|
||||||
|
cf = CertificateFactory.getInstance("X.509");
|
||||||
|
InputStream caInput = DownloadManager.APP.getAssets().open(caPath);
|
||||||
|
Certificate ca;
|
||||||
|
ca = cf.generateCertificate(caInput);
|
||||||
|
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
|
||||||
|
|
||||||
|
// Create a KeyStore containing our trusted CAs
|
||||||
|
String keyStoreType = KeyStore.getDefaultType();
|
||||||
|
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||||
|
keyStore.load(null, null);
|
||||||
|
keyStore.setCertificateEntry(caAlias, ca);
|
||||||
|
|
||||||
|
// Create a TrustManager that trusts the CAs in our KeyStore
|
||||||
|
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||||
|
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
|
||||||
|
tmf.init(keyStore);
|
||||||
|
KeyManagerFactory kmf =
|
||||||
|
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||||
|
kmf.init(keyStore, null);
|
||||||
|
|
||||||
|
// Create an SSLContext that uses our TrustManager
|
||||||
|
SSLContext context = SSLContext.getInstance("TLS");
|
||||||
|
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
|
||||||
|
return context;
|
||||||
|
} catch (CertificateException | NoSuchAlgorithmException | IOException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器证书不是由 CA 签署的,而是自签署时,获取默认的SSL
|
||||||
|
*/
|
||||||
|
public static SSLContext getDefaultSLLContext() {
|
||||||
|
SSLContext sslContext = null;
|
||||||
|
try {
|
||||||
|
sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(null, new TrustManager[] { trustManagers }, new SecureRandom());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return sslContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建自己的 TrustManager,这次直接信任服务器证书。这种方法具有前面所述的将应用与证书直接关联的所有弊端,但可以安全地操作。
|
||||||
|
*/
|
||||||
|
private static TrustManager trustManagers = new 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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() {
|
||||||
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -49,10 +49,10 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
|||||||
public static final int DOWNLOAD_RESUME = 0x05;
|
public static final int DOWNLOAD_RESUME = 0x05;
|
||||||
public static final int DOWNLOAD_COMPLETE = 0x06;
|
public static final int DOWNLOAD_COMPLETE = 0x06;
|
||||||
public static final int DOWNLOAD_RUNNING = 0x07;
|
public static final int DOWNLOAD_RUNNING = 0x07;
|
||||||
|
|
||||||
private static final String DOWNLOAD_URL =
|
private static final String DOWNLOAD_URL =
|
||||||
"http://static.gaoshouyou.com/d/3a/93/573ae1db9493a801c24bf66128b11e39.apk";
|
//"http://kotlinlang.org/docs/kotlin-docs.pdf";
|
||||||
//private static final String DOWNLOAD_URL =
|
"https://dl.google.com/dl/android/studio/install/2.2.3.0/android-studio-bundle-145.3537739-windows.exe";
|
||||||
// "http://www.yangqiang.im/wp-content/uploads/2016/10/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.png";
|
|
||||||
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb;
|
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb;
|
||||||
@Bind(R.id.start) Button mStart;
|
@Bind(R.id.start) Button mStart;
|
||||||
@Bind(R.id.stop) Button mStop;
|
@Bind(R.id.stop) Button mStop;
|
||||||
@ -114,6 +114,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
|||||||
setBtState(false);
|
setBtState(false);
|
||||||
break;
|
break;
|
||||||
case DOWNLOAD_COMPLETE:
|
case DOWNLOAD_COMPLETE:
|
||||||
|
mPb.setProgress(100);
|
||||||
Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
|
Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
|
||||||
mStart.setText("重新开始?");
|
mStart.setText("重新开始?");
|
||||||
mCancel.setEnabled(false);
|
mCancel.setEnabled(false);
|
||||||
|
Reference in New Issue
Block a user