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. 89
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java
  4. 50
      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. 43
      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; package com.arialyy.aria.core;
import com.arialyy.aria.orm.annotation.Ignore;
import java.net.InetAddress; import java.net.InetAddress;
/** /**
@ -32,6 +33,12 @@ public class FtpUrlEntity implements Cloneable {
public String account; public String account;
/**
* 是否是ftps
* {@code true}ftps协议的地址{@code false}不是ftps协议的地址
*/
public boolean isFtps = false;
/** /**
* 原始url * 原始url
*/ */
@ -46,9 +53,11 @@ public class FtpUrlEntity implements Cloneable {
* 登录的用户名 * 登录的用户名
*/ */
public String user; public String user;
/** /**
* 密码 * 密码
*/ */
@Ignore
public String password; public String password;
/** /**
@ -71,6 +80,26 @@ public class FtpUrlEntity implements Cloneable {
*/ */
public InetAddress validAddr; public InetAddress validAddr;
/**
* 证书路径
*/
public String storePath;
/**
* 证书密码
*/
public String storePass;
/**
* SSL协议
*/
public String SSLProtocol;
/**
* 私钥别名
*/
public String keyAlias;
@Override public FtpUrlEntity clone() { @Override public FtpUrlEntity clone() {
FtpUrlEntity entity = null; FtpUrlEntity entity = null;
try { 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.common; package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.FtpUrlEntity; 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.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.Regular; import com.arialyy.aria.util.Regular;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.net.ssl.SSLContext;
import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
/** /**
* Created by Aria.Lao on 2017/7/25. * Created by Aria.Lao on 2017/7/25.
@ -78,9 +83,11 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
} }
String remotePath = String remotePath =
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET); 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); FTPFile[] files = client.listFiles(remotePath);
String s = client.getReplyString();
ALog.i(TAG, s);
boolean isExist = files.length != 0; boolean isExist = files.length != 0;
if (!isExist && !isUpload) { if (!isExist && !isUpload) {
failDownload(String.format("文件不存在,任务链接【%s】,remotePath:%s", mTaskEntity.getUrlEntity().url, 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, ALog.i(TAG,
"================================= --end-- ==================================="); "================================= --end-- ===================================");
} else { } else {
String msg = client.getReplyString(); ALog.w(TAG, String.format("获取文件列表失败,msg:%s", client.getReplyString()));
ALog.w(TAG, msg);
} }
client.disconnect(); client.disconnect();
return; return;
@ -128,15 +134,12 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mTaskEntity.update(); mTaskEntity.update();
onPreComplete(reply); onPreComplete(reply);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace();
ALog.e(TAG,
String.format("FTP错误信息,code:%s,msg:%s", client.getReplyCode(), client.getReplyString()));
failDownload(e.getMessage(), true); failDownload(e.getMessage(), true);
} finally { } finally {
if (client != null) { closeClient(client);
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
} }
@ -172,7 +175,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
Pattern p = Pattern.compile(Regular.REG_IP_V4); Pattern p = Pattern.compile(Regular.REG_IP_V4);
Matcher m = p.matcher(urlEntity.hostName); Matcher m = p.matcher(urlEntity.hostName);
if (m.find() && m.groupCount() > 0) { if (m.find() && m.groupCount() > 0) {
client = new FTPClient(); client = newInstanceClient(urlEntity);
InetAddress ip = InetAddress.getByName(urlEntity.hostName); InetAddress ip = InetAddress.getByName(urlEntity.hostName);
client.setConnectTimeout(mConnectTimeOut); // 连接10s超时 client.setConnectTimeout(mConnectTimeOut); // 连接10s超时
client.connect(ip, Integer.parseInt(urlEntity.port)); client.connect(ip, Integer.parseInt(urlEntity.port));
@ -182,7 +185,13 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
dnsThread.start(); dnsThread.start();
dnsThread.join(mConnectTimeOut); dnsThread.join(mConnectTimeOut);
InetAddress[] ips = dnsThread.getIps(); 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) { 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); loginSuccess = client.login(urlEntity.user, urlEntity.password, urlEntity.account);
} }
} catch (IOException e) { } catch (IOException e) {
ALog.e(TAG, client.getReplyString()); ALog.e(TAG, String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(),
client.getReplyString()));
return null; return null;
} }
} }
if (!loginSuccess) { if (!loginSuccess) {
failDownload("登录失败", false); failDownload(
String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(), client.getReplyString()),
false);
client.disconnect();
return null; return null;
} }
@ -219,23 +232,59 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8"; charSet = "UTF-8";
reply = client.sendCommand("OPTS UTF8", "ON"); reply = client.sendCommand("OPTS UTF8", "ON");
if (!TextUtils.isEmpty(mTaskEntity.getCharSet()) || (!FTPReply.isPositiveCompletion(reply) if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
&& reply != FTPReply.COMMAND_OK)) {
ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码"); ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
charSet = mTaskEntity.getCharSet(); if (!TextUtils.isEmpty(mTaskEntity.getCharSet())) {
charSet = mTaskEntity.getCharSet();
}
} }
client.setControlEncoding(charSet); client.setControlEncoding(charSet);
client.setDataTimeout(10 * 1000); client.setDataTimeout(10 * 1000);
client.enterLocalPassiveMode(); client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE); client.setFileType(FTP.BINARY_FILE_TYPE);
} catch (IOException e) { } catch (IOException e) {
closeClient(client);
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {
closeClient(client);
e.printStackTrace(); e.printStackTrace();
} }
return client; 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服务器 * 连接到ftp服务器
*/ */
@ -268,7 +317,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
e1.printStackTrace(); e1.printStackTrace();
} }
ALog.w(TAG, "遇到[ECONNREFUSED-连接被服务器拒绝]错误,正在尝试下一个地址"); 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.common; package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity; 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.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEventListener; import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.net.ssl.SSLContext;
import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
/** /**
* Created by lyy on 2017/9/26. * 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>> public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
extends AbsThreadTask<ENTITY, TASK_ENTITY> { extends AbsThreadTask<ENTITY, TASK_ENTITY> {
private final String TAG = "AbsFtpThreadTask"; private final String TAG = "AbsFtpThreadTask";
protected String charSet, port; protected String charSet;
/** /**
* D_FTP 服务器编码 * D_FTP 服务器编码
*/ */
@ -55,7 +62,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
if (urlEntity.validAddr == null) { if (urlEntity.validAddr == null) {
try { try {
InetAddress[] ips = InetAddress.getAllByName(urlEntity.hostName); 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) { if (client == null) {
return null; return null;
} }
@ -63,7 +70,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
client = new FTPClient(); client = newInstanceClient(urlEntity);
try { try {
client.connect(urlEntity.validAddr, Integer.parseInt(urlEntity.port)); client.connect(urlEntity.validAddr, Integer.parseInt(urlEntity.port));
} catch (IOException e) { } catch (IOException e) {
@ -77,6 +84,12 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
} }
try { 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 (urlEntity.needLogin) {
if (TextUtils.isEmpty(urlEntity.account)) { if (TextUtils.isEmpty(urlEntity.account)) {
client.login(urlEntity.user, urlEntity.password); client.login(urlEntity.user, urlEntity.password);
@ -93,9 +106,10 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
} }
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8"; charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.getCharSet()) || !FTPReply.isPositiveCompletion( if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
client.sendCommand("OPTS UTF8", "ON"))) { if (!TextUtils.isEmpty(mTaskEntity.getCharSet())) {
charSet = mTaskEntity.getCharSet(); charSet = mTaskEntity.getCharSet();
}
} }
client.setControlEncoding(charSet); client.setControlEncoding(charSet);
client.setDataTimeout(mReadTimeOut); client.setDataTimeout(mReadTimeOut);
@ -103,12 +117,34 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
client.enterLocalPassiveMode(); client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE); client.setFileType(FTP.BINARY_FILE_TYPE);
client.setControlKeepAliveTimeout(5000); client.setControlKeepAliveTimeout(5000);
if (mTaskEntity.getUrlEntity().isFtps) {
((FTPSClient) client).execPROT("P");
}
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return client; 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服务器 * 连接到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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.delegate; package com.arialyy.aria.core.common.ftp;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.inf.ITarget;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
/** /**
* Created by laoyuyu on 2018/3/9. * Created by laoyuyu on 2018/3/9.
* ftp 委托 * ftp 委托
*/ */
public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET> {
implements IFtpTarget<TARGET> {
private static final String TAG = "FtpDelegate"; private static final String TAG = "FtpDelegate";
private ENTITY mEntity; private FtpUrlEntity mUrlEntity;
private TASK_ENTITY mTaskEntity;
private TARGET mTarget; private TARGET mTarget;
public FtpDelegate(TARGET target, TASK_ENTITY taskEntity) { public FtpDelegate(TARGET target) {
mTarget = target; mTarget = target;
mTaskEntity = taskEntity; mUrlEntity = target.getTaskEntity().getUrlEntity();
mEntity = mTaskEntity.getEntity();
} }
@Override public TARGET charSet(String charSet) { @Override public TARGET charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) return mTarget; if (TextUtils.isEmpty(charSet)) {
mTaskEntity.setCharSet(charSet); throw new NullPointerException("字符编码为空");
}
mTarget.getTaskEntity().setCharSet(charSet);
return mTarget; return mTarget;
} }
@ -57,10 +55,10 @@ public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_
ALog.e(TAG, "密码不能为null"); ALog.e(TAG, "密码不能为null");
return mTarget; return mTarget;
} }
mTaskEntity.getUrlEntity().needLogin = true; mUrlEntity.needLogin = true;
mTaskEntity.getUrlEntity().user = userName; mUrlEntity.user = userName;
mTaskEntity.getUrlEntity().password = password; mUrlEntity.password = password;
mTaskEntity.getUrlEntity().account = account; mUrlEntity.account = account;
return mTarget; 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.delegate; package com.arialyy.aria.core.common.http;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum; 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.AbsTaskEntity;
import com.arialyy.aria.core.inf.IHttpHeaderTarget; import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import com.arialyy.aria.core.inf.ITarget;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import java.net.Proxy;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -31,18 +31,13 @@ import java.util.Set;
* Created by laoyuyu on 2018/3/9. * Created by laoyuyu on 2018/3/9.
* HTTP header参数设置委托类 * 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> { implements IHttpHeaderTarget<TARGET> {
private static final String TAG = "HttpHeaderDelegate"; private static final String TAG = "HttpHeaderDelegate";
private ENTITY mEntity;
private TASK_ENTITY mTaskEntity;
private TARGET mTarget; private TARGET mTarget;
public HttpHeaderDelegate(TARGET target, TASK_ENTITY taskEntity) { public HttpHeaderDelegate(TARGET target) {
mTarget = 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"); ALog.w(TAG, "设置header失败,header对应的value不能为null");
return mTarget; return mTarget;
} }
addHeader(mTaskEntity, key, value); addHeader(mTarget.getTaskEntity(), key, value);
return mTarget; return mTarget;
} }
@ -77,7 +72,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
ALog.w(TAG, "设置header失败,map没有header数据"); ALog.w(TAG, "设置header失败,map没有header数据");
return mTarget; return mTarget;
} }
addHeaders(mTaskEntity, headers); addHeaders(mTarget.getTaskEntity(), headers);
return mTarget; return mTarget;
} }
@ -89,7 +84,12 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/ */
@Override @Override
public TARGET setRequestMode(RequestEnum requestEnum) { 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; return mTarget;
} }

@ -19,13 +19,14 @@ import android.support.annotation.CheckResult;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum; 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.inf.IHttpHeaderTarget;
import com.arialyy.aria.core.manager.TEManager; import com.arialyy.aria.core.manager.TEManager;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.io.File; import java.io.File;
import java.net.Proxy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -38,8 +39,7 @@ import java.util.Set;
*/ */
public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> implements public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> implements
IHttpHeaderTarget<DownloadGroupTarget> { IHttpHeaderTarget<DownloadGroupTarget> {
private HttpHeaderDelegate<DownloadGroupTarget, DownloadGroupEntity, DownloadGroupTaskEntity> private HttpHeaderDelegate<DownloadGroupTarget> mDelegate;
mDelegate;
/** /**
* 子任务下载地址 * 子任务下载地址
*/ */
@ -71,7 +71,35 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
if (mEntity != null) { if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath(); 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; return true;
} }
@CheckResult
@Override public DownloadGroupTarget addHeader(@NonNull String key, @NonNull String value) { @Override public DownloadGroupTarget addHeader(@NonNull String key, @NonNull String value) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
mDelegate.addHeader(subTask, key, value); mDelegate.addHeader(subTask, key, value);
@ -275,6 +304,7 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
return mDelegate.addHeader(key, value); return mDelegate.addHeader(key, value);
} }
@CheckResult
@Override public DownloadGroupTarget addHeaders(Map<String, String> headers) { @Override public DownloadGroupTarget addHeaders(Map<String, String> headers) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
mDelegate.addHeaders(subTask, headers); mDelegate.addHeaders(subTask, headers);
@ -282,10 +312,16 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> im
return mDelegate.addHeaders(headers); return mDelegate.addHeaders(headers);
} }
@CheckResult
@Override public DownloadGroupTarget setRequestMode(RequestEnum requestEnum) { @Override public DownloadGroupTarget setRequestMode(RequestEnum requestEnum) {
for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) { for (DownloadTaskEntity subTask : mTaskEntity.getSubTaskEntities()) {
subTask.setRequestEnum(requestEnum); subTask.setRequestEnum(requestEnum);
} }
return mDelegate.setRequestMode(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.CheckResult;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum; 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.inf.IHttpHeaderTarget;
import java.net.Proxy; import java.net.Proxy;
import java.util.Map; import java.util.Map;
@ -29,7 +29,7 @@ import java.util.Map;
*/ */
public class DownloadTarget extends BaseNormalTarget<DownloadTarget> public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
implements IHttpHeaderTarget<DownloadTarget> { implements IHttpHeaderTarget<DownloadTarget> {
private HttpHeaderDelegate<DownloadTarget, DownloadEntity, DownloadTaskEntity> mDelegate; private HttpHeaderDelegate<DownloadTarget> mDelegate;
DownloadTarget(DownloadEntity entity, String targetName) { DownloadTarget(DownloadEntity entity, String targetName) {
@ -38,7 +38,7 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
DownloadTarget(String url, String targetName) { DownloadTarget(String url, String targetName) {
initTarget(url, 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; return this;
} }
/**
* 设置URL的代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
public DownloadTarget setUrlProxy(Proxy proxy) {
mTaskEntity.setProxy(proxy);
return this;
}
/** /**
* 设置文件存储路径 * 设置文件存储路径
* 该api后续版本会删除 * 该api后续版本会删除
@ -100,6 +89,17 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
return HTTP; return HTTP;
} }
/**
* 设置URL的代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
@Override public DownloadTarget setUrlProxy(Proxy proxy) {
return mDelegate.setUrlProxy(proxy);
}
@CheckResult @CheckResult
@Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) { @Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) {
return mDelegate.addHeader(key, value); return mDelegate.addHeader(key, value);

@ -17,7 +17,7 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult; import android.support.annotation.CheckResult;
import android.text.TextUtils; 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.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.manager.TEManager; import com.arialyy.aria.core.manager.TEManager;
@ -29,7 +29,7 @@ import com.arialyy.aria.util.ALog;
*/ */
public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget> public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
implements IFtpTarget<FtpDirDownloadTarget> { implements IFtpTarget<FtpDirDownloadTarget> {
private FtpDelegate<FtpDirDownloadTarget, DownloadGroupEntity, DownloadGroupTaskEntity> mDelegate; private FtpDelegate<FtpDirDownloadTarget> mDelegate;
FtpDirDownloadTarget(String url, String targetName) { FtpDirDownloadTarget(String url, String targetName) {
mTargetName = targetName; mTargetName = targetName;
@ -44,7 +44,7 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
if (mEntity != null) { if (mEntity != null) {
mDirPathTemp = mEntity.getDirPath(); mDirPathTemp = mEntity.getDirPath();
} }
mDelegate = new FtpDelegate<>(this, mTaskEntity); mDelegate = new FtpDelegate<>(this);
} }
@Override protected int getTargetType() { @Override protected int getTargetType() {
@ -90,14 +90,17 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
} }
return true; return true;
} }
@CheckResult @CheckResult
@Override public FtpDirDownloadTarget charSet(String charSet) { @Override public FtpDirDownloadTarget charSet(String charSet) {
return mDelegate.charSet(charSet); return mDelegate.charSet(charSet);
} }
@CheckResult @CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password) { @Override public FtpDirDownloadTarget login(String userName, String password) {
return mDelegate.login(userName, password); return mDelegate.login(userName, password);
} }
@CheckResult @CheckResult
@Override public FtpDirDownloadTarget login(String userName, String password, String account) { @Override public FtpDirDownloadTarget login(String userName, String password, String account) {
return mDelegate.login(userName, password, 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.CheckResult;
import android.support.annotation.NonNull; 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.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
@ -28,7 +29,7 @@ import com.arialyy.aria.util.CommonUtil;
*/ */
public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget> public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
implements IFtpTarget<FtpDownloadTarget> { implements IFtpTarget<FtpDownloadTarget> {
private FtpDelegate<FtpDownloadTarget, DownloadEntity, DownloadTaskEntity> mDelegate; private FtpDelegate<FtpDownloadTarget> mDelegate;
public FtpDownloadTarget(DownloadEntity entity, String targetName) { public FtpDownloadTarget(DownloadEntity entity, String targetName) {
this(entity.getUrl(), targetName); this(entity.getUrl(), targetName);
@ -45,7 +46,18 @@ public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(url)); mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(url));
mTaskEntity.setRequestType(AbsTaskEntity.D_FTP); 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; package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -26,8 +27,6 @@ import java.net.HttpURLConnection;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
@ -75,9 +74,11 @@ class ConnectionHelp {
urlConn = url.openConnection(); urlConn = url.openConnection();
} }
if (urlConn instanceof HttpsURLConnection) { if (urlConn instanceof HttpsURLConnection) {
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
conn = (HttpsURLConnection) urlConn; conn = (HttpsURLConnection) urlConn;
SSLContext sslContext = SSLContext sslContext =
SSLContextUtil.getSSLContext(SSLContextUtil.CA_ALIAS, SSLContextUtil.CA_PATH); SSLContextUtil.getSSLContextFromAssets(manager.getDownloadConfig().getCaName(),
manager.getDownloadConfig().getCaPath());
if (sslContext == null) { if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext(); sslContext = SSLContextUtil.getDefaultSLLContext();
} }
@ -126,24 +127,24 @@ class ConnectionHelp {
if (conn.getRequestProperty("Accept") == null) { if (conn.getRequestProperty("Accept") == null) {
StringBuilder accept = new StringBuilder(); StringBuilder accept = new StringBuilder();
//accept //accept
//.append("image/gif, ") //.append("image/gif, ")
//.append("image/jpeg, ") //.append("image/jpeg, ")
//.append("image/pjpeg, ") //.append("image/pjpeg, ")
//.append("image/webp, ") //.append("image/webp, ")
//.append("image/apng, ") //.append("image/apng, ")
//.append("application/xml, ") //.append("application/xml, ")
//.append("application/xaml+xml, ") //.append("application/xaml+xml, ")
//.append("application/xhtml+xml, ") //.append("application/xhtml+xml, ")
//.append("application/x-shockwave-flash, ") //.append("application/x-shockwave-flash, ")
//.append("application/x-ms-xbap, ") //.append("application/x-ms-xbap, ")
//.append("application/x-ms-application, ") //.append("application/x-ms-application, ")
//.append("application/msword, ") //.append("application/msword, ")
//.append("application/vnd.ms-excel, ") //.append("application/vnd.ms-excel, ")
//.append("application/vnd.ms-xpsdocument, ") //.append("application/vnd.ms-xpsdocument, ")
//.append("application/vnd.ms-powerpoint, ") //.append("application/vnd.ms-powerpoint, ")
//.append("text/plain, ") //.append("text/plain, ")
//.append("text/html, ") //.append("text/html, ")
//.append("*/*"); //.append("*/*");
conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Accept", "*/*");
} }
//302获取重定向地址 //302获取重定向地址

@ -16,9 +16,9 @@
package com.arialyy.aria.core.download.downloader; package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.FtpUrlEntity; 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.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback; 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.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity;

@ -15,7 +15,7 @@
*/ */
package com.arialyy.aria.core.download.downloader; 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.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;

@ -16,7 +16,7 @@
package com.arialyy.aria.core.download.downloader; package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.AriaManager; 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.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;

@ -37,7 +37,7 @@ import java.util.List;
* Created by AriaL on 2017/7/3. * Created by AriaL on 2017/7/3.
*/ */
public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity> public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity>
implements ITarget<TARGET> { implements ITarget {
protected String TAG; protected String TAG;
protected ENTITY mEntity; protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity; 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 该任务进度 * @return 该任务进度
*/ */
@Override
public long getCurrentProgress() { public long getCurrentProgress() {
return mEntity == null ? -1 : mEntity.getCurrentProgress(); return mEntity == null ? -1 : mEntity.getCurrentProgress();
} }
@ -97,7 +103,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
* *
* @return 文件大小 * @return 文件大小
*/ */
@Override public long getSize() { public long getSize() {
return mEntity == null ? 0 : mEntity.getFileSize(); return mEntity == null ? 0 : mEntity.getFileSize();
} }
@ -106,7 +112,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
* *
* @return 文件大小{@code xxx mb} * @return 文件大小{@code xxx mb}
*/ */
@Override public String getConvertSize() { public String getConvertSize() {
return mEntity == null ? "0b" : CommonUtil.formatFileSize(mEntity.getFileSize()); 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} * @return {@link IEntity}
*/ */
@Override
public int getTaskState() { public int getTaskState() {
return mEntity.getState(); return mEntity.getState();
} }
@ -152,7 +157,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
* *
* @return 返回任务进度 * @return 返回任务进度
*/ */
@Override public int getPercent() { public int getPercent() {
if (mEntity == null) { if (mEntity == null) {
ALog.e("AbsTarget", "下载管理器中没有该任务"); ALog.e("AbsTarget", "下载管理器中没有该任务");
return 0; 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 android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import java.net.Proxy;
import java.util.Map; import java.util.Map;
/** /**
@ -53,4 +54,7 @@ public interface IHttpHeaderTarget<TARGET extends ITarget> {
*/ */
@CheckResult @CheckResult
TARGET setRequestMode(RequestEnum requestEnum); 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. * Created by AriaL on 2017/6/29.
*/ */
public interface ITarget<TARGET extends ITarget> { public interface ITarget {
/**
* 获取任务状态
*
* @return {@link IEntity}
*/
int getTaskState();
/**
* 任务是否在执行
*
* @return {@code true} 任务正在执行
*/
boolean isRunning();
/**
* 任务是否存在
*
* @return {@code true} 任务存在
*/
boolean taskExists();
/**
* 任务文件大小
*/
long getSize();
/**
* 转换后的大小
*/
String getConvertSize();
/**
* 获取任务进度百分比
*/
int getPercent();
/**
* 获取任务进度如果任务存在则返回当前进度
*/
long getCurrentProgress();
/** /**
* 开始下载 * 开始下载
*/ */

@ -18,7 +18,7 @@ package com.arialyy.aria.core.upload;
import android.support.annotation.CheckResult; import android.support.annotation.CheckResult;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.normal.NormalCmdFactory; 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.AbsTaskEntity;
import com.arialyy.aria.core.inf.IFtpTarget; import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
@ -29,7 +29,7 @@ import com.arialyy.aria.util.CommonUtil;
*/ */
public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget> public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
implements IFtpTarget<FtpUploadTarget> { implements IFtpTarget<FtpUploadTarget> {
private FtpDelegate<FtpUploadTarget, UploadEntity, UploadTaskEntity> mDelegate; private FtpDelegate<FtpUploadTarget> mDelegate;
private String mAccount, mUser, mPw; private String mAccount, mUser, mPw;
private boolean needLogin = false; private boolean needLogin = false;
@ -42,7 +42,7 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
private void initTask(String filePath) { private void initTask(String filePath) {
initTarget(filePath); initTarget(filePath);
mTaskEntity.setRequestType(AbsTaskEntity.U_FTP); 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.CheckResult;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.RequestEnum; 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.AbsTaskEntity;
import com.arialyy.aria.core.inf.IHttpHeaderTarget; import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import java.net.Proxy;
import java.util.Map; import java.util.Map;
/** /**
@ -29,7 +30,7 @@ import java.util.Map;
*/ */
public class UploadTarget extends BaseNormalTarget<UploadTarget> public class UploadTarget extends BaseNormalTarget<UploadTarget>
implements IHttpHeaderTarget<UploadTarget> { implements IHttpHeaderTarget<UploadTarget> {
private HttpHeaderDelegate<UploadTarget, UploadEntity, UploadTaskEntity> mDelegate; private HttpHeaderDelegate<UploadTarget> mDelegate;
UploadTarget(String filePath, String targetName) { UploadTarget(String filePath, String targetName) {
this.mTargetName = targetName; this.mTargetName = targetName;
@ -42,7 +43,7 @@ public class UploadTarget extends BaseNormalTarget<UploadTarget>
//http暂时不支持断点上传 //http暂时不支持断点上传
mTaskEntity.setSupportBP(false); mTaskEntity.setSupportBP(false);
mTaskEntity.setRequestType(AbsTaskEntity.U_HTTP); 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) { @Override public UploadTarget setRequestMode(RequestEnum requestEnum) {
return mDelegate.setRequestMode(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; 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.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.common.TaskRecord; import com.arialyy.aria.core.common.TaskRecord;

@ -16,7 +16,7 @@
package com.arialyy.aria.core.upload.uploader; package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.AriaManager; 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.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.inf.IEventListener; 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*/ /*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/
static Map<String, Class> mapping = new HashMap<>(); static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME; static String DB_NAME;
static int VERSION = 40; static int VERSION = 41;
/** /**
* 是否将数据库保存在Sd卡{@code true} * 是否将数据库保存在Sd卡{@code true}

@ -17,6 +17,7 @@ package com.arialyy.aria.util;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.KeyManagementException; import java.security.KeyManagementException;
@ -42,30 +43,46 @@ import javax.net.ssl.X509TrustManager;
* SSL证书工具 * SSL证书工具
*/ */
public class SSLContextUtil { 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 未知 * 颁发服务器证书的 CA 未知
* *
* @param caAlias CA证书别名 * @param caAlias CA证书别名
* @param caPath 保存在assets目录下的CA证书完整路径 * @param caPath CA证书路径
*/ */
public static SSLContext getSSLContext(String caAlias, String caPath) { public static SSLContext getSSLContext(String caAlias, String caPath) {
if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)) { if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)) {
return null; return null;
} }
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = null;
try { try {
cf = CertificateFactory.getInstance("X.509"); Certificate ca = loadCert(new FileInputStream(caPath));
InputStream caInput = AriaManager.APP.getAssets().open(caPath); return createContext(caAlias, ca);
Certificate ca; } catch (CertificateException | IOException e) {
ca = cf.generateCertificate(caInput); e.printStackTrace();
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); }
return null;
}
// Create a KeyStore containing our trusted CAs private static SSLContext createContext(String caAlias, Certificate ca) {
try {
String keyStoreType = KeyStore.getDefaultType(); String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType); KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null); keyStore.load(null, null);
@ -89,6 +106,20 @@ public class SSLContextUtil {
return null; 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 * 服务器证书不是由 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.7
- 修复分块任务异常操作导致的问题 - 修复分块任务异常操作导致的问题
+ v_3.4.6 + v_3.4.6

@ -17,9 +17,9 @@
<!--android:name=".test.TestGroupActivity"--> <!--android:name=".test.TestGroupActivity"-->
<!--android:name=".MainActivity"--> <!--android:name=".MainActivity"-->
<!--android:name="com.arialyy.simple.test.AnyRunActivity"--> <!--android:name="com.arialyy.simple.test.AnyRunActivity"-->
<!--android:name=".test.AnyRunActivity"--> <!--android:name=".download.group.DownloadGroupActivity"-->
<activity <activity
android:name=".download.group.DownloadGroupActivity" android:name=".test.AnyRunActivity"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <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.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityDownloadGroupBinding; import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
import com.arialyy.simple.widget.SubStateLinearLayout; import com.arialyy.simple.widget.SubStateLinearLayout;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -80,6 +81,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: 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) Aria.download(this)
.loadGroup(mUrls) .loadGroup(mUrls)
.setDirPath( .setDirPath(
@ -88,7 +91,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
.setGroupAlias("任务组测试") .setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName2()) //.setSubFileName(getModule(GroupModule.class).getSubName2())
.setSubFileName(getModule(GroupModule.class).getSubName()) .setSubFileName(getModule(GroupModule.class).getSubName())
//.setFileSize(32895492) .updateUrls(temp)
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:

@ -39,8 +39,9 @@ public class GroupModule extends BaseModule {
List<String> getUrls1() { List<String> getUrls1() {
List<String> urls = new ArrayList<>(); List<String> urls = new ArrayList<>();
String[] str = getContext().getResources().getStringArray(R.array.group_urls); //String[] str = getContext().getResources().getStringArray(R.array.group_urls);
Collections.addAll(urls, str); //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; 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"; //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 = "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 = "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"; //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 = "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"; //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) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
module.start(URL); //module.start(URL);
//module.startFtp(URL); module.startFtp(URL);
break; break;
case R.id.stop: case R.id.stop:
module.stop(URL); module.stop(URL);

@ -10,7 +10,6 @@ import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L; import com.arialyy.frame.util.show.L;
import java.io.File; import java.io.File;
import java.net.Proxy;
/** /**
* Created by laoyuyu on 2018/4/13. * Created by laoyuyu on 2018/4/13.
@ -79,7 +78,11 @@ public class AnyRunnModule {
Aria.download(this) Aria.download(this)
.loadFtp(url) .loadFtp(url)
.login("lao", "123456") .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(); .start();
} }

Loading…
Cancel
Save