ftps 支持

pull/330/head
laoyuyu 7 years ago
parent 1ca3ff900d
commit d1e591b448
  1. 29
      Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java
  2. 39
      Aria/src/main/java/com/arialyy/aria/core/common/ProtocolType.java
  3. 87
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java
  4. 48
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpThreadTask.java
  5. 104
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSSLConfig.java
  6. 32
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java
  7. 54
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/SSLSessionReuseFTPSClient.java
  8. 26
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpHeaderDelegate.java
  9. 44
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  10. 28
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  11. 9
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  12. 18
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
  13. 7
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
  15. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
  16. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  17. 31
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  18. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java
  19. 43
      Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
  20. 6
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  21. 11
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  22. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  23. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  24. 2
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  25. 53
      Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java
  26. 4
      DEV_LOG.md
  27. 4
      app/src/main/AndroidManifest.xml
  28. 5
      app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
  29. 5
      app/src/main/java/com/arialyy/simple/download/group/GroupModule.java
  30. 7
      app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java
  31. 7
      app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java

@ -17,6 +17,7 @@
*/
package com.arialyy.aria.core;
import com.arialyy.aria.orm.annotation.Ignore;
import java.net.InetAddress;
/**
@ -32,6 +33,12 @@ public class FtpUrlEntity implements Cloneable {
public String account;
/**
* 是否是ftps
* {@code true}ftps协议的地址{@code false}不是ftps协议的地址
*/
public boolean isFtps = false;
/**
* 原始url
*/
@ -46,9 +53,11 @@ public class FtpUrlEntity implements Cloneable {
* 登录的用户名
*/
public String user;
/**
* 密码
*/
@Ignore
public String password;
/**
@ -71,6 +80,26 @@ public class FtpUrlEntity implements Cloneable {
*/
public InetAddress validAddr;
/**
* 证书路径
*/
public String storePath;
/**
* 证书密码
*/
public String storePass;
/**
* SSL协议
*/
public String SSLProtocol;
/**
* 私钥别名
*/
public String keyAlias;
@Override public FtpUrlEntity clone() {
FtpUrlEntity entity = null;
try {

@ -0,0 +1,39 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* 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 com.arialyy.aria.core.common;
import android.support.annotation.StringDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@StringDef({
ProtocolType.Default,
ProtocolType.SSL,
ProtocolType.SSLv3,
ProtocolType.TLS,
ProtocolType.TLSv1,
ProtocolType.TLSv1_1,
ProtocolType.TLSv1_2
})
@Retention(RetentionPolicy.SOURCE) public @interface ProtocolType {
String Default = "Default";
String SSL = "SSL";
String SSLv3 = "SSLv3";
String TLS = "TLS";
String TLSv1 = "TLSv1";
String TLSv1_1 = "TLSv1.1";
String TLSv1_2 = "TLSv1.2";
}

@ -13,26 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.common;
package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.Regular;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLContext;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
/**
* Created by Aria.Lao on 2017/7/25.
@ -78,9 +83,11 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
}
String remotePath =
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
if (mTaskEntity.getUrlEntity().isFtps) {
((FTPSClient) client).execPROT("P");
//((FTPSClient) client).setEnabledSessionCreation(false);
}
FTPFile[] files = client.listFiles(remotePath);
String s = client.getReplyString();
ALog.i(TAG, s);
boolean isExist = files.length != 0;
if (!isExist && !isUpload) {
failDownload(String.format("文件不存在,任务链接【%s】,remotePath:%s", mTaskEntity.getUrlEntity().url,
@ -101,8 +108,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
ALog.i(TAG,
"================================= --end-- ===================================");
} else {
String msg = client.getReplyString();
ALog.w(TAG, msg);
ALog.w(TAG, String.format("获取文件列表失败,msg:%s", client.getReplyString()));
}
client.disconnect();
return;
@ -128,15 +134,12 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mTaskEntity.update();
onPreComplete(reply);
} catch (IOException e) {
e.printStackTrace();
ALog.e(TAG,
String.format("FTP错误信息,code:%s,msg:%s", client.getReplyCode(), client.getReplyString()));
failDownload(e.getMessage(), true);
} finally {
if (client != null) {
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
closeClient(client);
}
}
@ -172,7 +175,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
Pattern p = Pattern.compile(Regular.REG_IP_V4);
Matcher m = p.matcher(urlEntity.hostName);
if (m.find() && m.groupCount() > 0) {
client = new FTPClient();
client = newInstanceClient(urlEntity);
InetAddress ip = InetAddress.getByName(urlEntity.hostName);
client.setConnectTimeout(mConnectTimeOut); // 连接10s超时
client.connect(ip, Integer.parseInt(urlEntity.port));
@ -182,7 +185,13 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
dnsThread.start();
dnsThread.join(mConnectTimeOut);
InetAddress[] ips = dnsThread.getIps();
client = connect(new FTPClient(), ips, 0, Integer.parseInt(urlEntity.port));
client = connect(newInstanceClient(urlEntity), ips, 0, Integer.parseInt(urlEntity.port));
}
if (urlEntity.isFtps) {
int code = ((FTPSClient) client).execAUTH(
TextUtils.isEmpty(urlEntity.SSLProtocol) ? ProtocolType.TLS : urlEntity.SSLProtocol);
ALog.d(TAG, String.format("cod:%s,msg:%s", code, client.getReplyString()));
}
if (client == null) {
@ -199,13 +208,17 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
loginSuccess = client.login(urlEntity.user, urlEntity.password, urlEntity.account);
}
} catch (IOException e) {
ALog.e(TAG, client.getReplyString());
ALog.e(TAG, String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(),
client.getReplyString()));
return null;
}
}
if (!loginSuccess) {
failDownload("登录失败", false);
failDownload(
String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(), client.getReplyString()),
false);
client.disconnect();
return null;
}
@ -219,23 +232,59 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8";
reply = client.sendCommand("OPTS UTF8", "ON");
if (!TextUtils.isEmpty(mTaskEntity.getCharSet()) || (!FTPReply.isPositiveCompletion(reply)
&& reply != FTPReply.COMMAND_OK)) {
if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
if (!TextUtils.isEmpty(mTaskEntity.getCharSet())) {
charSet = mTaskEntity.getCharSet();
}
}
client.setControlEncoding(charSet);
client.setDataTimeout(10 * 1000);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
} catch (IOException e) {
closeClient(client);
e.printStackTrace();
} catch (InterruptedException e) {
closeClient(client);
e.printStackTrace();
}
return client;
}
private void closeClient(FTPClient client) {
try {
if (client != null && client.isConnected()) {
client.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 创建FTP/FTPS客户端
*/
private FTPClient newInstanceClient(FtpUrlEntity urlEntity) {
FTPClient temp = null;
if (urlEntity.isFtps) {
SSLContext sslContext =
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath);
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
}
//System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
//temp = new SSLSessionReuseFTPSClient(true, sslContext);
FTPSClient client = new FTPSClient(true, sslContext);
temp = client;
} else {
temp = new FTPClient();
}
return temp;
}
/**
* 连接到ftp服务器
*/
@ -268,7 +317,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
e1.printStackTrace();
}
ALog.w(TAG, "遇到[ECONNREFUSED-连接被服务器拒绝]错误,正在尝试下一个地址");
return connect(new FTPClient(), ips, index + 1, port);
return connect(newInstanceClient(mTaskEntity.getUrlEntity()), ips, index + 1, port);
}
}

@ -13,20 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.common;
package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.net.ssl.SSLContext;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
/**
* Created by lyy on 2017/9/26.
@ -35,7 +42,7 @@ import org.apache.commons.net.ftp.FTPReply;
public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
extends AbsThreadTask<ENTITY, TASK_ENTITY> {
private final String TAG = "AbsFtpThreadTask";
protected String charSet, port;
protected String charSet;
/**
* D_FTP 服务器编码
*/
@ -55,7 +62,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
if (urlEntity.validAddr == null) {
try {
InetAddress[] ips = InetAddress.getAllByName(urlEntity.hostName);
client = connect(new FTPClient(), ips, 0, Integer.parseInt(urlEntity.port));
client = connect(newInstanceClient(urlEntity), ips, 0, Integer.parseInt(urlEntity.port));
if (client == null) {
return null;
}
@ -63,7 +70,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
e.printStackTrace();
}
} else {
client = new FTPClient();
client = newInstanceClient(urlEntity);
try {
client.connect(urlEntity.validAddr, Integer.parseInt(urlEntity.port));
} catch (IOException e) {
@ -77,6 +84,12 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
}
try {
if (urlEntity.isFtps) {
int code = ((FTPSClient) client).execAUTH(
TextUtils.isEmpty(urlEntity.SSLProtocol) ? ProtocolType.TLS : urlEntity.SSLProtocol);
ALog.d(TAG, String.format("cod:%s,msg:%s", code, client.getReplyString()));
}
if (urlEntity.needLogin) {
if (TextUtils.isEmpty(urlEntity.account)) {
client.login(urlEntity.user, urlEntity.password);
@ -93,22 +106,45 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
}
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.getCharSet()) || !FTPReply.isPositiveCompletion(
client.sendCommand("OPTS UTF8", "ON"))) {
if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
if (!TextUtils.isEmpty(mTaskEntity.getCharSet())) {
charSet = mTaskEntity.getCharSet();
}
}
client.setControlEncoding(charSet);
client.setDataTimeout(mReadTimeOut);
client.setConnectTimeout(mConnectTimeOut);
client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setControlKeepAliveTimeout(5000);
if (mTaskEntity.getUrlEntity().isFtps) {
((FTPSClient) client).execPROT("P");
}
} catch (IOException e) {
e.printStackTrace();
}
return client;
}
/**
* 创建FTP/FTPS客户端
*/
private FTPClient newInstanceClient(FtpUrlEntity urlEntity) {
FTPClient temp;
if (urlEntity.isFtps) {
SSLContext sslContext =
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath);
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
}
temp = new FTPSClient(true, sslContext);
} else {
temp = new FTPClient();
}
return temp;
}
/**
* 连接到ftp服务器
*/

@ -0,0 +1,104 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* 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 com.arialyy.aria.core.common.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.ITarget;
/**
* FTP SSL/TSL配置
*/
public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
private final String TAG = "FTPSSLConfig";
private TARGET mTarget;
private FtpUrlEntity mUrlEntity;
public FTPSSLConfig(TARGET target) {
mTarget = target;
mUrlEntity = mTarget.getTaskEntity().getUrlEntity();
}
/**
* 设置协议类型
*
* @param protocol {@link ProtocolType}
*/
public FTPSSLConfig setProtocol(@ProtocolType String protocol) {
if (TextUtils.isEmpty(protocol)) {
throw new NullPointerException("协议为空");
}
mUrlEntity.SSLProtocol = protocol;
return this;
}
/**
* 设置证书别名
*
* @param keyAlias 别名
*/
public FTPSSLConfig setAlias(String keyAlias) {
if (TextUtils.isEmpty(keyAlias)) {
throw new NullPointerException("别名为空");
}
mUrlEntity.keyAlias = keyAlias;
return this;
}
/**
* 设置证书密码
*
* @param storePass 私钥密码
*/
public FTPSSLConfig setStorePass(String storePass) {
if (TextUtils.isEmpty(storePass)) {
throw new NullPointerException("证书密码为空");
}
mUrlEntity.storePass = storePass;
return this;
}
/**
* 设置证书路径
*
* @param storePath 证书路径
*/
public FTPSSLConfig setStorePath(String storePath) {
if (TextUtils.isEmpty(storePath)) {
throw new NullPointerException("证书路径为空");
}
mUrlEntity.storePath = storePath;
return this;
}
@Override public void start() {
mTarget.start();
}
@Override public void stop() {
mTarget.stop();
}
@Override public void resume() {
mTarget.resume();
}
@Override public void cancel() {
mTarget.cancel();
}
}

@ -13,35 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.delegate;
package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.inf.ITarget;
import com.arialyy.aria.util.ALog;
/**
* Created by laoyuyu on 2018/3/9.
* ftp 委托
*/
public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements IFtpTarget<TARGET> {
public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET> {
private static final String TAG = "FtpDelegate";
private ENTITY mEntity;
private TASK_ENTITY mTaskEntity;
private FtpUrlEntity mUrlEntity;
private TARGET mTarget;
public FtpDelegate(TARGET target, TASK_ENTITY taskEntity) {
public FtpDelegate(TARGET target) {
mTarget = target;
mTaskEntity = taskEntity;
mEntity = mTaskEntity.getEntity();
mUrlEntity = target.getTaskEntity().getUrlEntity();
}
@Override public TARGET charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) return mTarget;
mTaskEntity.setCharSet(charSet);
if (TextUtils.isEmpty(charSet)) {
throw new NullPointerException("字符编码为空");
}
mTarget.getTaskEntity().setCharSet(charSet);
return mTarget;
}
@ -57,10 +55,10 @@ public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_
ALog.e(TAG, "密码不能为null");
return mTarget;
}
mTaskEntity.getUrlEntity().needLogin = true;
mTaskEntity.getUrlEntity().user = userName;
mTaskEntity.getUrlEntity().password = password;
mTaskEntity.getUrlEntity().account = account;
mUrlEntity.needLogin = true;
mUrlEntity.user = userName;
mUrlEntity.password = password;
mUrlEntity.account = account;
return mTarget;
}
}

@ -0,0 +1,54 @@
package com.arialyy.aria.core.common.ftp;
import com.arialyy.aria.util.ALog;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import org.apache.commons.net.ftp.FTPSClient;
public class SSLSessionReuseFTPSClient extends FTPSClient {
SSLSessionReuseFTPSClient(boolean b, SSLContext context) {
super(b, context);
}
// adapted from:
// https://trac.cyberduck.io/browser/trunk/ftp/src/main/java/ch/cyberduck/core/ftp/FTPClient.java
@Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
// Control socket is SSL
final SSLSession session = ((SSLSocket) _socket_).getSession();
if (session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
try {
//final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
final Field sessionHostPortCache =
context.getClass().getDeclaredField("sessionsByHostAndPort");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method method =
cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
method.setAccessible(true);
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostName(),
String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session);
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostAddress(),
String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session);
ALog.d("tag", "GGGG");
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (Exception e) {
throw new IOException(e);
}
} else {
throw new IOException("Invalid SSL Session");
}
}
}
}

@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.delegate;
package com.arialyy.aria.core.common.http;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import com.arialyy.aria.core.inf.ITarget;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@ -31,18 +31,13 @@ import java.util.Set;
* Created by laoyuyu on 2018/3/9.
* HTTP header参数设置委托类
*/
public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
public class HttpHeaderDelegate<TARGET extends AbsTarget>
implements IHttpHeaderTarget<TARGET> {
private static final String TAG = "HttpHeaderDelegate";
private ENTITY mEntity;
private TASK_ENTITY mTaskEntity;
private TARGET mTarget;
public HttpHeaderDelegate(TARGET target, TASK_ENTITY taskEntity) {
public HttpHeaderDelegate(TARGET target) {
mTarget = target;
mTaskEntity = taskEntity;
mEntity = mTaskEntity.getEntity();
}
/**
@ -61,7 +56,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
ALog.w(TAG, "设置header失败,header对应的value不能为null");
return mTarget;
}
addHeader(mTaskEntity, key, value);
addHeader(mTarget.getTaskEntity(), key, value);
return mTarget;
}
@ -77,7 +72,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
ALog.w(TAG, "设置header失败,map没有header数据");
return mTarget;
}
addHeaders(mTaskEntity, headers);
addHeaders(mTarget.getTaskEntity(), headers);
return mTarget;
}
@ -89,7 +84,12 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/
@Override
public TARGET setRequestMode(RequestEnum requestEnum) {
setRequestMode(mTaskEntity, requestEnum);
setRequestMode(mTarget.getTaskEntity(), requestEnum);
return mTarget;
}
@Override public TARGET setUrlProxy(Proxy proxy) {
mTarget.getTaskEntity().setProxy(proxy);
return mTarget;
}

@ -19,13 +19,14 @@ import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.delegate.HttpHeaderDelegate;
import com.arialyy.aria.core.common.http.HttpHeaderDelegate;
import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import com.arialyy.aria.core.manager.TEManager;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -38,8 +39,7 @@ import java.util.Set;
*/
public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> implements
IHttpHeaderTarget<DownloadGroupTarget> {
private HttpHeaderDelegate<DownloadGroupTarget, DownloadGroupEntity, DownloadGroupTaskEntity>
mDelegate;
private HttpHeaderDelegate<DownloadGroupTarget> mDelegate;
/**
* 子任务下载地址
*/
@ -71,7 +71,35 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath();
}
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
mDelegate = new HttpHeaderDelegate<>(this);
}
/**
* 更新组合任务下载地址
*
* @param urls 新的组合任务下载地址列表
*/
@CheckResult
public DownloadGroupTarget updateUrls(List<String> urls) {
if (urls == null || urls.isEmpty()) {
throw new NullPointerException("下载地址列表为空");
}
if (urls.size() != mUrls.size()) {
throw new IllegalArgumentException("新下载地址数量和旧下载地址数量不一致");
}
mUrls.clear();
mUrls.addAll(urls);
mGroupName = CommonUtil.getMd5Code(urls);
mEntity.setGroupName(mGroupName);
mTaskEntity.setKey(mGroupName);
mEntity.update();
if (mEntity.getSubEntities() != null && !mEntity.getSubEntities().isEmpty()) {
for (DownloadEntity de : mEntity.getSubEntities()) {
de.setGroupName(mGroupName);
de.update();
}
}
return this;
}
/**
@ -268,6 +296,7 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
return true;
}
@CheckResult
@Override public DownloadGroupTarget addHeader(@NonNull String key, @NonNull String value) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
mDelegate.addHeader(subTask, key, value);
@ -275,6 +304,7 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
return mDelegate.addHeader(key, value);
}
@CheckResult
@Override public DownloadGroupTarget addHeaders(Map<String, String> headers) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
mDelegate.addHeaders(subTask, headers);
@ -282,10 +312,16 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
return mDelegate.addHeaders(headers);
}
@CheckResult
@Override public DownloadGroupTarget setRequestMode(RequestEnum requestEnum) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
subTask.setRequestEnum(requestEnum);
}
return mDelegate.setRequestMode(requestEnum);
}
@CheckResult
@Override public DownloadGroupTarget setUrlProxy(Proxy proxy) {
return mDelegate.setUrlProxy(proxy);
}
}

@ -18,7 +18,7 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.delegate.HttpHeaderDelegate;
import com.arialyy.aria.core.common.http.HttpHeaderDelegate;
import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import java.net.Proxy;
import java.util.Map;
@ -29,7 +29,7 @@ import java.util.Map;
*/
public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
implements IHttpHeaderTarget<DownloadTarget> {
private HttpHeaderDelegate<DownloadTarget, DownloadEntity, DownloadTaskEntity> mDelegate;
private HttpHeaderDelegate<DownloadTarget> mDelegate;
DownloadTarget(DownloadEntity entity, String targetName) {
@ -38,7 +38,7 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
DownloadTarget(String url, String targetName) {
initTarget(url, targetName);
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
mDelegate = new HttpHeaderDelegate<>(this);
}
/**
@ -53,17 +53,6 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
return this;
}
/**
* 设置URL的代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
public DownloadTarget setUrlProxy(Proxy proxy) {
mTaskEntity.setProxy(proxy);
return this;
}
/**
* 设置文件存储路径
* 该api后续版本会删除
@ -100,6 +89,17 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
return HTTP;
}
/**
* 设置URL的代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
@Override public DownloadTarget setUrlProxy(Proxy proxy) {
return mDelegate.setUrlProxy(proxy);
}
@CheckResult
@Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) {
return mDelegate.addHeader(key, value);

@ -17,7 +17,7 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.delegate.FtpDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.manager.TEManager;
@ -29,7 +29,7 @@ import com.arialyy.aria.util.ALog;
*/
public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
implements IFtpTarget<FtpDirDownloadTarget> {
private FtpDelegate<FtpDirDownloadTarget, DownloadGroupEntity, DownloadGroupTaskEntity> mDelegate;
private FtpDelegate<FtpDirDownloadTarget> mDelegate;
FtpDirDownloadTarget(String url, String targetName) {
mTargetName = targetName;
@ -44,7 +44,7 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath();
}
mDelegate = new FtpDelegate<>(this, mTaskEntity);
mDelegate = new FtpDelegate<>(this);
}
@Override protected int getTargetType() {
@ -90,14 +90,17 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
}
return true;
}
@CheckResult
@Override public FtpDirDownloadTarget charSet(String charSet) {
return mDelegate.charSet(charSet);
}
@CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password) {
return mDelegate.login(userName, password);
}
@CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password, String account) {
return mDelegate.login(userName, password, account);

@ -17,7 +17,8 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.delegate.FtpDelegate;
import com.arialyy.aria.core.common.ftp.FTPSSLConfig;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CommonUtil;
@ -28,7 +29,7 @@ import com.arialyy.aria.util.CommonUtil;
*/
public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
implements IFtpTarget<FtpDownloadTarget> {
private FtpDelegate<FtpDownloadTarget, DownloadEntity, DownloadTaskEntity> mDelegate;
private FtpDelegate<FtpDownloadTarget> mDelegate;
public FtpDownloadTarget(DownloadEntity entity, String targetName) {
this(entity.getUrl(), targetName);
@ -45,7 +46,18 @@ public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(url));
mTaskEntity.setRequestType(AbsTaskEntity.D_FTP);
mDelegate = new FtpDelegate<>(this, mTaskEntity);
mDelegate = new FtpDelegate<>(this);
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSSLConfig#setPrivateKeyPath(String)}{@link FTPSSLConfig#setCertPath(String)}
* 设置证书信息
*/
@CheckResult
public FTPSSLConfig<FtpDownloadTarget> asFtps() {
mTaskEntity.getUrlEntity().isFtps = true;
return new FTPSSLConfig<>(this);
}
/**

@ -16,6 +16,7 @@
package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -26,8 +27,6 @@ import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
@ -75,9 +74,11 @@ class ConnectionHelp {
urlConn = url.openConnection();
}
if (urlConn instanceof HttpsURLConnection) {
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
conn = (HttpsURLConnection) urlConn;
SSLContext sslContext =
SSLContextUtil.getSSLContext(SSLContextUtil.CA_ALIAS, SSLContextUtil.CA_PATH);
SSLContextUtil.getSSLContextFromAssets(manager.getDownloadConfig().getCaName(),
manager.getDownloadConfig().getCaPath());
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
}

@ -16,9 +16,9 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;

@ -16,7 +16,7 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsFtpThreadTask;
import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.download.DownloadEntity;

@ -37,7 +37,7 @@ import java.util.List;
* Created by AriaL on 2017/7/3.
*/
public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity>
implements ITarget<TARGET> {
implements ITarget {
protected String TAG;
protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity;
@ -82,12 +82,18 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
}
/**
* 获取任务实体
*/
public TASK_ENTITY getTaskEntity() {
return mTaskEntity;
}
/**
* 获取任务进度如果任务存在则返回当前进度
*
* @return 该任务进度
*/
@Override
public long getCurrentProgress() {
return mEntity == null ? -1 : mEntity.getCurrentProgress();
}
@ -97,7 +103,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*
* @return 文件大小
*/
@Override public long getSize() {
public long getSize() {
return mEntity == null ? 0 : mEntity.getFileSize();
}
@ -106,7 +112,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*
* @return 文件大小{@code xxx mb}
*/
@Override public String getConvertSize() {
public String getConvertSize() {
return mEntity == null ? "0b" : CommonUtil.formatFileSize(mEntity.getFileSize());
}
@ -142,7 +148,6 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*
* @return {@link IEntity}
*/
@Override
public int getTaskState() {
return mEntity.getState();
}
@ -152,7 +157,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*
* @return 返回任务进度
*/
@Override public int getPercent() {
public int getPercent() {
if (mEntity == null) {
ALog.e("AbsTarget", "下载管理器中没有该任务");
return 0;
@ -191,6 +196,20 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
}
}
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行
*/
public abstract boolean isRunning();
/**
* 任务是否存在
*
* @return {@code true} 任务存在
*/
public abstract boolean taskExists();
/**
* 开始任务
*/

@ -19,6 +19,7 @@ import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadEntity;
import java.net.Proxy;
import java.util.Map;
/**
@ -53,4 +54,7 @@ public interface IHttpHeaderTarget<TARGET extends ITarget> {
*/
@CheckResult
TARGET setRequestMode(RequestEnum requestEnum);
@CheckResult
TARGET setUrlProxy(Proxy proxy);
}

@ -18,48 +18,7 @@ package com.arialyy.aria.core.inf;
/**
* Created by AriaL on 2017/6/29.
*/
public interface ITarget<TARGET extends ITarget> {
/**
* 获取任务状态
*
* @return {@link IEntity}
*/
int getTaskState();
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行
*/
boolean isRunning();
/**
* 任务是否存在
*
* @return {@code true} 任务存在
*/
boolean taskExists();
/**
* 任务文件大小
*/
long getSize();
/**
* 转换后的大小
*/
String getConvertSize();
/**
* 获取任务进度百分比
*/
int getPercent();
/**
* 获取任务进度如果任务存在则返回当前进度
*/
long getCurrentProgress();
public interface ITarget {
/**
* 开始下载
*/

@ -18,7 +18,7 @@ package com.arialyy.aria.core.upload;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.delegate.FtpDelegate;
import com.arialyy.aria.core.common.ftp.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CommonUtil;
@ -29,7 +29,7 @@ import com.arialyy.aria.util.CommonUtil;
*/
public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
implements IFtpTarget<FtpUploadTarget> {
private FtpDelegate<FtpUploadTarget, UploadEntity, UploadTaskEntity> mDelegate;
private FtpDelegate<FtpUploadTarget> mDelegate;
private String mAccount, mUser, mPw;
private boolean needLogin = false;
@ -42,7 +42,7 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
private void initTask(String filePath) {
initTarget(filePath);
mTaskEntity.setRequestType(AbsTaskEntity.U_FTP);
mDelegate = new FtpDelegate<>(this, mTaskEntity);
mDelegate = new FtpDelegate<>(this);
}
/**

@ -18,9 +18,10 @@ package com.arialyy.aria.core.upload;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.delegate.HttpHeaderDelegate;
import com.arialyy.aria.core.common.http.HttpHeaderDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import java.net.Proxy;
import java.util.Map;
/**
@ -29,7 +30,7 @@ import java.util.Map;
*/
public class UploadTarget extends BaseNormalTarget<UploadTarget>
implements IHttpHeaderTarget<UploadTarget> {
private HttpHeaderDelegate<UploadTarget, UploadEntity, UploadTaskEntity> mDelegate;
private HttpHeaderDelegate<UploadTarget> mDelegate;
UploadTarget(String filePath, String targetName) {
this.mTargetName = targetName;
@ -42,7 +43,7 @@ public class UploadTarget extends BaseNormalTarget<UploadTarget>
//http暂时不支持断点上传
mTaskEntity.setSupportBP(false);
mTaskEntity.setRequestType(AbsTaskEntity.U_HTTP);
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
mDelegate = new HttpHeaderDelegate<>(this);
}
/**
@ -90,4 +91,8 @@ public class UploadTarget extends BaseNormalTarget<UploadTarget>
@Override public UploadTarget setRequestMode(RequestEnum requestEnum) {
return mDelegate.setRequestMode(requestEnum);
}
@Override public UploadTarget setUrlProxy(Proxy proxy) {
return mDelegate.setUrlProxy(proxy);
}
}

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
import com.arialyy.aria.core.common.ftp.AbsFtpInfoThread;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.common.TaskRecord;

@ -16,7 +16,7 @@
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsFtpThreadTask;
import com.arialyy.aria.core.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.inf.IEventListener;

@ -35,7 +35,7 @@ class DBConfig {
/*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/
static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME;
static int VERSION = 40;
static int VERSION = 41;
/**
* 是否将数据库保存在Sd卡{@code true}

@ -17,6 +17,7 @@ package com.arialyy.aria.util;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
@ -42,30 +43,46 @@ import javax.net.ssl.X509TrustManager;
* SSL证书工具
*/
public class SSLContextUtil {
private static final String TAG = "SSLContextUtil";
public static String CA_PATH, CA_ALIAS;
/**
* 从assets目录下加载证书
*
* @param caAlias CA证书别名
* @param caPath 保存在assets目录下的CA证书完整路径
*/
public static SSLContext getSSLContextFromAssets(String caAlias, String caPath) {
try {
InputStream caInput = AriaManager.APP.getAssets().open(caPath);
Certificate ca = loadCert(caInput);
return createContext(caAlias, ca);
} catch (IOException | CertificateException e) {
e.printStackTrace();
}
return null;
}
/**
* 颁发服务器证书的 CA 未知
*
* @param caAlias CA证书别名
* @param caPath 保存在assets目录下的CA证书完整路径
* @param caPath CA证书路径
*/
public static SSLContext getSSLContext(String caAlias, String caPath) {
if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)) {
return null;
}
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream caInput = AriaManager.APP.getAssets().open(caPath);
Certificate ca;
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
Certificate ca = loadCert(new FileInputStream(caPath));
return createContext(caAlias, ca);
} catch (CertificateException | IOException e) {
e.printStackTrace();
}
return null;
}
// Create a KeyStore containing our trusted CAs
private static SSLContext createContext(String caAlias, Certificate ca) {
try {
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
@ -89,6 +106,20 @@ public class SSLContextUtil {
return null;
}
/**
* 加载CA证书
*
* @param is CA证书文件流
* @throws CertificateException
*/
private static Certificate loadCert(InputStream is) throws CertificateException, IOException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate ca = cf.generateCertificate(is);
ALog.d(TAG, String.format("ca【%s】", ((X509Certificate) ca).getSubjectDN()));
is.close();
return ca;
}
/**
* 服务器证书不是由 CA 签署的而是自签署时获取默认的SSL
*/

@ -1,4 +1,8 @@
## 开发日志
+ v_3.4.8
- 组合任务新增`updateUrls(List<String>)`用于修改组合子任务的url,[see](https://aria.laoyuyu.me/aria_doc/api/task_handle.html#%E6%9B%B4%E6%96%B0%E4%BB%BB%E5%8A%A1url)
- 出于安全考虑,FTP数据库去掉密码的保存
- 增加FTPS支持 [see]()
+ v_3.4.7
- 修复分块任务异常操作导致的问题
+ v_3.4.6

@ -17,9 +17,9 @@
<!--android:name=".test.TestGroupActivity"-->
<!--android:name=".MainActivity"-->
<!--android:name="com.arialyy.simple.test.AnyRunActivity"-->
<!--android:name=".test.AnyRunActivity"-->
<!--android:name=".download.group.DownloadGroupActivity"-->
<activity
android:name=".download.group.DownloadGroupActivity"
android:name=".test.AnyRunActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

@ -32,6 +32,7 @@ import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
import com.arialyy.simple.widget.SubStateLinearLayout;
import java.util.ArrayList;
import java.util.List;
/**
@ -80,6 +81,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
List<String> temp = new ArrayList<>();
temp.add("https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134714&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-h8KgJ6gl4oY9UR6NqvwJsT4nVSM%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401996296756616039&dp-callid=0&r=279987343");
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(
@ -88,7 +91,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
.setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName2())
.setSubFileName(getModule(GroupModule.class).getSubName())
//.setFileSize(32895492)
.updateUrls(temp)
.start();
break;
case R.id.stop:

@ -39,8 +39,9 @@ public class GroupModule extends BaseModule {
List<String> getUrls1() {
List<String> urls = new ArrayList<>();
String[] str = getContext().getResources().getStringArray(R.array.group_urls);
Collections.addAll(urls, str);
//String[] str = getContext().getResources().getStringArray(R.array.group_urls);
//Collections.addAll(urls, str);
urls.add("https://d.pcs.baidu.com/file/130335545f3f4d9cc38afe709c19af5a?fid=1411168371-250528-1010657263806840&dstime=1531134607&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-sNCujT7lC42aMcfiHcgqAzYHuw4%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4401967667009194668&dp-callid=0&r=540192514");
return urls;
}

@ -28,7 +28,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
//private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar";
//String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
//String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk";
String URL = "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176";
String URL = "ftps://192.168.29.140:990/download/SDK_Demo-release.apk";
//String URL = "http://d.quanscreen.com/k/down/resourceDownLoad?resourceId=1994&clientId=A000011106034058176";
//String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";
//private String URL = "https://www.bilibili.com/bangumi/play/ep77693";
//private String URL = "http://cn-hbsjz-cmcc-v-03.acgvideo.com/upgcxcode/63/82/5108263/5108263-1-80.flv?expires=1530178500&platform=pc&ssig=vr7gLl0duyqWqSMnIpzaDA&oi=3746029570&nfa=BpfiWF+i4mNW8KzjZFHzBQ==&dynamic=1&hfa=2030547937&hfb=Yjk5ZmZjM2M1YzY4ZjAwYTMzMTIzYmIyNWY4ODJkNWI=&trid=3476be01a9254115b15f8cc7198600fe&nfc=1";
@ -50,8 +51,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
module.start(URL);
//module.startFtp(URL);
//module.start(URL);
module.startFtp(URL);
break;
case R.id.stop:
module.stop(URL);

@ -10,7 +10,6 @@ import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import java.io.File;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/4/13.
@ -79,7 +78,11 @@ public class AnyRunnModule {
Aria.download(this)
.loadFtp(url)
.login("lao", "123456")
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/")
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/Download/")
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
.setStorePass("123456")
.start();
}

Loading…
Cancel
Save