ftps 上传/下载优化,上传/下载速度限制实现

pull/330/head
laoyuyu 6 years ago
parent d1e591b448
commit 5bdc1c881b
  1. 3
      Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
  2. 9
      Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java
  3. 38
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  4. 39
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  5. 104
      Aria/src/main/java/com/arialyy/aria/core/common/BandwidthLimiter.java
  6. 6
      Aria/src/main/java/com/arialyy/aria/core/common/IUtil.java
  7. 2
      Aria/src/main/java/com/arialyy/aria/core/common/ProtocolType.java
  8. 12
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpInfoThread.java
  9. 7
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/AbsFtpThreadTask.java
  10. 16
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FTPSConfig.java
  11. 6
      Aria/src/main/java/com/arialyy/aria/core/common/ftp/FtpDelegate.java
  12. 4
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  13. 10
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  14. 36
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  15. 14
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
  16. 10
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
  17. 5
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
  18. 9
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
  19. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
  20. 34
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  21. 29
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  22. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
  23. 8
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTask.java
  24. 13
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java
  25. 9
      Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java
  26. 14
      Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
  27. 12
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
  28. 33
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  29. 10
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  30. 29
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  31. 17
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  32. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java
  33. 18
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  34. 45
      Aria/src/main/java/com/arialyy/aria/util/SSLContextUtil.java
  35. 1
      DEV_LOG.md
  36. 10
      app/src/main/AndroidManifest.xml
  37. 7
      app/src/main/assets/aria_config.xml
  38. 16
      app/src/main/java/com/arialyy/simple/test/TestFTPActivity.java
  39. 8
      app/src/main/java/com/arialyy/simple/test/TestFTPDirActivity.java
  40. 45
      aria/src/main/java/com/arialyy/aria/core/Configuration.java
  41. 1
      aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java

@ -184,6 +184,9 @@ class ConfigHelper extends DefaultHandler {
if (mType == ConfigType.DOWNLOAD) {
mDownloadConfig.maxSpeed = maxSpeed;
}
if (mType == ConfigType.UPLOAD) {
mUploadConfig.maxSpeed = maxSpeed;
}
}
private void loadConvertSpeed(String value) {

@ -17,6 +17,7 @@
*/
package com.arialyy.aria.core;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.orm.annotation.Ignore;
import java.net.InetAddress;
@ -47,7 +48,7 @@ public class FtpUrlEntity implements Cloneable {
/**
* ftp协议ftp
*/
public String protocol;
public String scheme;
/**
* 登录的用户名
@ -91,9 +92,11 @@ public class FtpUrlEntity implements Cloneable {
public String storePass;
/**
* SSL协议
* 连接协议
* {@link ProtocolType}
*/
public String SSLProtocol;
@ProtocolType
public String protocol;
/**
* 私钥别名

@ -21,7 +21,6 @@ import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
@ -45,7 +44,7 @@ import java.util.concurrent.Executors;
* 任务处理器
*/
public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable, IUtil {
implements Runnable {
private static final String STATE = "_state_";
private static final String RECORD = "_record_";
/**
@ -93,7 +92,12 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mTaskEntity.setNewTask(newTask);
}
@Override public void setMaxSpeed(double maxSpeed) {
/**
* 设置最大下载/上传速度
*
* @param maxSpeed 单位为kb
*/
public void setMaxSpeed(int maxSpeed) {
for (int i = 0; i < mTotalThreadNum; i++) {
AbsThreadTask task = mTask.get(i);
if (task != null) {
@ -143,9 +147,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
checkRecord();
mConstance.isRunning = true;
mConstance.TASK_RECORD = mRecord;
if (mListener instanceof IDownloadListener) {
((IDownloadListener) mListener).onPostPre(mEntity.getFileSize());
}
if (!mTaskEntity.isSupportBP()) {
mTotalThreadNum = 1;
mStartThreadNum = 1;
@ -173,6 +174,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mRecord.isOpenDynamicFile = true;
}
onPostPre();
if (!mTaskEntity.isSupportBP()) {
handleNoSupportBP();
} else {
@ -182,6 +185,13 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
startTimer();
}
/**
* 预处理完成
*/
protected void onPostPre() {
}
/**
* 设置新任务的最大线程数
*/
@ -229,22 +239,22 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mUpdateInterval = interval;
}
@Override public long getFileSize() {
public long getFileSize() {
return mEntity.getFileSize();
}
/**
* 获取当前任务位置
*/
@Override public long getCurrentLocation() {
public long getCurrentLocation() {
return mConstance.CURRENT_LOCATION;
}
@Override public boolean isRunning() {
public boolean isRunning() {
return mConstance.isRunning;
}
@Override public void cancel() {
public void cancel() {
closeTimer();
mConstance.isRunning = false;
mConstance.isCancel = true;
@ -259,7 +269,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
}
}
@Override public void stop() {
public void stop() {
closeTimer();
mConstance.isRunning = false;
mConstance.isStop = true;
@ -278,11 +288,11 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
/**
* 直接调用的时候会自动启动线程执行
*/
@Override public void start() {
public void start() {
new Thread(this).start();
}
@Override public void resume() {
public void resume() {
start();
}
@ -395,7 +405,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
if (realLocation != tr.startLocation) {
ALog.i(TAG, String.format("修正分块【%s】的进度记录为:%s", temp.getPath(), realLocation));
tr.startLocation = realLocation;
}else if (realLocation > tr.endLocation) {
} else if (realLocation > tr.endLocation) {
ALog.i(TAG, String.format("分块【%s】错误,将重新开始该分块", temp.getPath()));
temp.delete();
tr.startLocation = i * blockLen;

@ -26,7 +26,6 @@ import com.arialyy.aria.util.ErrorHelp;
import com.arialyy.aria.util.FileUtil;
import com.arialyy.aria.util.NetUtils;
import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
@ -49,7 +48,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
/**
* 当前子线程的下载位置
*/
protected long mChildCurrentLocation = 0, mSleepTime = 0;
protected long mChildCurrentLocation = 0;
protected int mBufSize;
protected IEventListener mListener;
protected StateConstance STATE;
@ -64,6 +63,12 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
protected int mReadTimeOut; //流读取的超时时间
protected boolean isNotNetRetry = false; //断网情况是否重试
private boolean taskBreak = false; //任务中断
protected int mThreadNum;
/**
* 速度限制工具
*/
protected BandwidthLimiter mSpeedBandUtil;
protected AriaManager mAridManager;
private Thread mConfigThread = new Thread(new Runnable() {
@Override public void run() {
@ -81,15 +86,10 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
mEntity = mTaskEntity.getEntity();
mLastSaveTime = System.currentTimeMillis();
mConfigThreadPool = Executors.newCachedThreadPool();
}
protected void setMaxSpeed(double maxSpeed) {
if (-0.9999 < maxSpeed && maxSpeed < 0.00001) {
mSleepTime = 0;
} else {
BigDecimal db = new BigDecimal(
((mBufSize / 1024) * (filterVersion() ? 1 : STATE.START_THREAD_NUM) / maxSpeed) * 1000);
mSleepTime = db.setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
mThreadNum = STATE.TASK_RECORD.threadRecords.size();
mAridManager = AriaManager.getInstance(AriaManager.APP);
if (getMaxSpeed() > 0) {
mSpeedBandUtil = new BandwidthLimiter(getMaxSpeed(), mThreadNum);
}
}
@ -115,6 +115,23 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
return mConfig.THREAD_RECORD;
}
/**
* 获取配置的最大上传/下载速度
*
* @return 单位为kb
*/
public abstract int getMaxSpeed();
/**
* 设置最大下载速度
* @param speed 单位为kb
*/
public void setMaxSpeed(int speed){
if (mSpeedBandUtil != null){
mSpeedBandUtil.setMaxRate(speed / mThreadNum);
}
}
/**
* 中断任务
*/

@ -0,0 +1,104 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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;
/**
* 速度限制
*/
public class BandwidthLimiter {
public static int maxBandWith = 2 * 1024; //KB
/* KB */
private static Long KB = 1024L;
/* The smallest count chunk length in bytes */
private static Long CHUNK_LENGTH = 1024L;
/* How many bytes will be sent or receive */
private int bytesWillBeSentOrReceive = 0;
/* When the last piece was sent or receive */
private long lastPieceSentOrReceiveTick = System.nanoTime();
/* Default rate is 1024KB/s */
private int maxRate = 1024;
/* Time cost for sending CHUNK_LENGTH bytes in nanoseconds */
private long timeCostPerChunk = (1000000000L * CHUNK_LENGTH)
/ (this.maxRate * KB);
/**
* Initialize a BandwidthLimiter object with a certain rate.
*
* @param maxRate the download or upload speed in KBytes
*/
public BandwidthLimiter(int maxRate, int threadNum) {
if (threadNum > 1) {
maxRate = maxRate / threadNum;
}
this.setMaxRate(maxRate);
}
/**
* Set the max upload or download rate in KB/s. maxRate must be grater than
* 0. If maxRate is zero, it means there is no bandwidth limit.
*
* @param maxRate If maxRate is zero, it means there is no bandwidth limit.
* @throws IllegalArgumentException
*/
public synchronized void setMaxRate(int maxRate)
throws IllegalArgumentException {
if (maxRate < 0) {
throw new IllegalArgumentException("maxRate can not less than 0");
}
this.maxRate = maxRate;
if (maxRate == 0) {
this.timeCostPerChunk = 0;
} else {
this.timeCostPerChunk = (1000000000L * CHUNK_LENGTH)
/ (this.maxRate * KB);
}
}
/**
* Next 1 byte should do bandwidth limit.
*/
public synchronized void limitNextBytes() {
this.limitNextBytes(1);
}
/**
* Next len bytes should do bandwidth limit
*/
public synchronized void limitNextBytes(int len) {
this.bytesWillBeSentOrReceive += len;
/* We have sent CHUNK_LENGTH bytes */
while (this.bytesWillBeSentOrReceive > CHUNK_LENGTH) {
long nowTick = System.nanoTime();
long missedTime = this.timeCostPerChunk
- (nowTick - this.lastPieceSentOrReceiveTick);
if (missedTime > 0) {
try {
Thread.currentThread().sleep(missedTime / 1000000,
(int) (missedTime % 1000000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.bytesWillBeSentOrReceive -= CHUNK_LENGTH;
this.lastPieceSentOrReceiveTick = nowTick
+ (missedTime > 0 ? missedTime : 0);
}
}
}

@ -60,7 +60,9 @@ public interface IUtil {
void resume();
/**
* 设置最大速度
* 设置最大下载/上传速度
*
* @param speed 单位kb
*/
void setMaxSpeed(double maxSpeed);
void setMaxSpeed(int speed);
}

@ -29,7 +29,7 @@ import java.lang.annotation.RetentionPolicy;
ProtocolType.TLSv1_2
})
@Retention(RetentionPolicy.SOURCE) public @interface ProtocolType {
String Default = "Default";
String Default = "TLS";
String SSL = "SSL";
String SSLv3 = "SSLv3";
String TLS = "TLS";

@ -85,7 +85,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
if (mTaskEntity.getUrlEntity().isFtps) {
((FTPSClient) client).execPROT("P");
//((FTPSClient) client).setEnabledSessionCreation(false);
//((FTPSClient) client).enterLocalActiveMode();
}
FTPFile[] files = client.listFiles(remotePath);
boolean isExist = files.length != 0;
@ -190,7 +190,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
if (urlEntity.isFtps) {
int code = ((FTPSClient) client).execAUTH(
TextUtils.isEmpty(urlEntity.SSLProtocol) ? ProtocolType.TLS : urlEntity.SSLProtocol);
TextUtils.isEmpty(urlEntity.protocol) ? ProtocolType.TLS : urlEntity.protocol);
ALog.d(TAG, String.format("cod:%s,msg:%s", code, client.getReplyString()));
}
@ -269,14 +269,16 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
FTPClient temp = null;
if (urlEntity.isFtps) {
SSLContext sslContext =
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath);
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath, urlEntity.protocol);
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
sslContext = SSLContextUtil.getDefaultSLLContext(urlEntity.protocol);
}
//System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
//temp = new SSLSessionReuseFTPSClient(true, sslContext);
//FTPSClient client = new SSLSessionReuseFTPSClient(true, sslContext);
FTPSClient client = new FTPSClient(true, sslContext);
//Log.d(TAG, "session = " + client.getEnableSessionCreation());
temp = client;
} else {
temp = new FTPClient();

@ -16,6 +16,7 @@
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.AbsThreadTask;
import com.arialyy.aria.core.common.ProtocolType;
@ -86,7 +87,7 @@ 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);
TextUtils.isEmpty(urlEntity.protocol) ? ProtocolType.TLS : urlEntity.protocol);
ALog.d(TAG, String.format("cod:%s,msg:%s", code, client.getReplyString()));
}
@ -133,9 +134,9 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
FTPClient temp;
if (urlEntity.isFtps) {
SSLContext sslContext =
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath);
SSLContextUtil.getSSLContext(urlEntity.keyAlias, urlEntity.storePath, urlEntity.protocol);
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
sslContext = SSLContextUtil.getDefaultSLLContext(urlEntity.protocol);
}
temp = new FTPSClient(true, sslContext);
} else {

@ -24,12 +24,12 @@ import com.arialyy.aria.core.inf.ITarget;
/**
* FTP SSL/TSL配置
*/
public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
private final String TAG = "FTPSSLConfig";
public class FTPSConfig<TARGET extends AbsTarget> implements ITarget {
private final String TAG = "FTPSConfig";
private TARGET mTarget;
private FtpUrlEntity mUrlEntity;
public FTPSSLConfig(TARGET target) {
public FTPSConfig(TARGET target) {
mTarget = target;
mUrlEntity = mTarget.getTaskEntity().getUrlEntity();
}
@ -39,11 +39,11 @@ public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
*
* @param protocol {@link ProtocolType}
*/
public FTPSSLConfig setProtocol(@ProtocolType String protocol) {
public FTPSConfig setProtocol(@ProtocolType String protocol) {
if (TextUtils.isEmpty(protocol)) {
throw new NullPointerException("协议为空");
}
mUrlEntity.SSLProtocol = protocol;
mUrlEntity.protocol = protocol;
return this;
}
@ -52,7 +52,7 @@ public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
*
* @param keyAlias 别名
*/
public FTPSSLConfig setAlias(String keyAlias) {
public FTPSConfig setAlias(String keyAlias) {
if (TextUtils.isEmpty(keyAlias)) {
throw new NullPointerException("别名为空");
}
@ -65,7 +65,7 @@ public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
*
* @param storePass 私钥密码
*/
public FTPSSLConfig setStorePass(String storePass) {
public FTPSConfig setStorePass(String storePass) {
if (TextUtils.isEmpty(storePass)) {
throw new NullPointerException("证书密码为空");
}
@ -78,7 +78,7 @@ public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget {
*
* @param storePath 证书路径
*/
public FTPSSLConfig setStorePath(String storePath) {
public FTPSConfig setStorePath(String storePath) {
if (TextUtils.isEmpty(storePath)) {
throw new NullPointerException("证书路径为空");
}

@ -20,6 +20,7 @@ import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
@ -61,4 +62,9 @@ public class FtpDelegate<TARGET extends AbsTarget> implements IFtpTarget<TARGET>
mUrlEntity.account = account;
return mTarget;
}
@Override public TARGET setProxy(Proxy proxy) {
mTarget.getTaskEntity().setProxy(proxy);
return mTarget;
}
}

@ -47,12 +47,12 @@ public class DownloadReceiver extends AbsReceiver {
/**
* 设置最大下载速度单位kb
* 该方法为实验性功能清不要轻易在生产环境中使用
*
* @param maxSpeed 为0表示不限速
*/
@Deprecated public void setMaxSpeed(int maxSpeed) {
public DownloadReceiver setMaxSpeed(int maxSpeed) {
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setMaxSpeed(maxSpeed);
return this;
}
/**

@ -35,7 +35,6 @@ public class DownloadTask extends AbsNormalTask<DownloadTaskEntity> {
private DownloadListener mListener;
private DownloadEntity mEntity;
private IUtil mUtil;
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
mTaskEntity = taskEntity;
@ -96,15 +95,6 @@ public class DownloadTask extends AbsNormalTask<DownloadTaskEntity> {
stop(true);
}
/**
* 设置最大下载速度单位kb
*
* @param maxSpeed 为0表示不限速
*/
public void setMaxSpeed(double maxSpeed) {
mUtil.setMaxSpeed(maxSpeed);
}
/**
* 开始下载
*/

@ -17,11 +17,14 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.ftp.FTPSConfig;
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;
import com.arialyy.aria.util.ALog;
import java.net.Proxy;
/**
* Created by Aria.Lao on 2017/7/26.
@ -58,11 +61,21 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
mTaskEntity.save();
if (mTaskEntity.getSubTaskEntities() != null) {
//初始化子项的登录信息
FtpUrlEntity tUrlEntity = mTaskEntity.getUrlEntity();
for (DownloadTaskEntity entity : mTaskEntity.getSubTaskEntities()) {
entity.getUrlEntity().needLogin = mTaskEntity.getUrlEntity().needLogin;
entity.getUrlEntity().account = mTaskEntity.getUrlEntity().account;
entity.getUrlEntity().user = mTaskEntity.getUrlEntity().user;
entity.getUrlEntity().password = mTaskEntity.getUrlEntity().password;
FtpUrlEntity urlEntity = entity.getUrlEntity();
urlEntity.needLogin = tUrlEntity.needLogin;
urlEntity.account = tUrlEntity.account;
urlEntity.user = tUrlEntity.user;
urlEntity.password = tUrlEntity.password;
// 处理ftps详细
if (tUrlEntity.isFtps) {
urlEntity.isFtps = true;
urlEntity.protocol = tUrlEntity.protocol;
urlEntity.storePath = tUrlEntity.storePath;
urlEntity.storePass = tUrlEntity.storePass;
urlEntity.keyAlias = tUrlEntity.keyAlias;
}
}
}
}
@ -91,6 +104,17 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
return true;
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSConfig<FtpDirDownloadTarget> asFtps() {
mTaskEntity.getUrlEntity().isFtps = true;
return new FTPSConfig<>(this);
}
@CheckResult
@Override public FtpDirDownloadTarget charSet(String charSet) {
return mDelegate.charSet(charSet);
@ -105,4 +129,8 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
@Override public FtpDirDownloadTarget login(String userName, String password, String account) {
return mDelegate.login(userName, password, account);
}
@Override public FtpDirDownloadTarget setProxy(Proxy proxy) {
return mDelegate.setProxy(proxy);
}
}

@ -17,11 +17,12 @@ package com.arialyy.aria.core.download;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.common.ftp.FTPSSLConfig;
import com.arialyy.aria.core.common.ftp.FTPSConfig;
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;
import java.net.Proxy;
/**
* Created by lyy on 2016/12/5.
@ -51,13 +52,13 @@ public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSSLConfig#setPrivateKeyPath(String)}{@link FTPSSLConfig#setCertPath(String)}
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSSLConfig<FtpDownloadTarget> asFtps() {
public FTPSConfig<FtpDownloadTarget> asFtps() {
mTaskEntity.getUrlEntity().isFtps = true;
return new FTPSSLConfig<>(this);
return new FTPSConfig<>(this);
}
/**
@ -102,4 +103,9 @@ public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
@Override public FtpDownloadTarget login(String userName, String password, String account) {
return mDelegate.login(userName, password, account);
}
@CheckResult
@Override public FtpDownloadTarget setProxy(Proxy proxy) {
return mDelegate.setProxy(proxy);
}
}

@ -312,8 +312,14 @@ public abstract class AbsGroupUtil implements IUtil {
start();
}
@Override public void setMaxSpeed(double maxSpeed) {
@Override public void setMaxSpeed(int speed) {
Set<String> keys = mDownloaderMap.keySet();
for (String key : keys) {
Downloader dt = mDownloaderMap.get(key);
if (dt != null) {
dt.setMaxSpeed(speed);
}
}
}
private void clearState() {

@ -17,6 +17,7 @@ package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.ProtocolType;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -78,9 +79,9 @@ class ConnectionHelp {
conn = (HttpsURLConnection) urlConn;
SSLContext sslContext =
SSLContextUtil.getSSLContextFromAssets(manager.getDownloadConfig().getCaName(),
manager.getDownloadConfig().getCaPath());
manager.getDownloadConfig().getCaPath(), ProtocolType.Default);
if (sslContext == null) {
sslContext = SSLContextUtil.getDefaultSLLContext();
sslContext = SSLContextUtil.getDefaultSLLContext(ProtocolType.Default);
}
SSLSocketFactory ssf = sslContext.getSocketFactory();
((HttpsURLConnection) conn).setSSLSocketFactory(ssf);

@ -83,6 +83,15 @@ class Downloader extends AbsFileer<DownloadEntity, DownloadTaskEntity> {
return false;
}
@Override protected void onPostPre() {
super.onPostPre();
((IDownloadListener) mListener).onPostPre(mEntity.getFileSize());
File file = new File(mEntity.getDownloadPath());
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
}
@Override protected AbsThreadTask selectThreadTask(SubThreadConfig<DownloadTaskEntity> config) {
switch (mTaskEntity.getRequestType()) {
case AbsTaskEntity.D_FTP:

@ -61,7 +61,7 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DownloadGro
final FtpUrlEntity urlEntity = mTaskEntity.getUrlEntity().clone();
DownloadEntity entity = new DownloadEntity();
entity.setUrl(
urlEntity.protocol + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath);
urlEntity.scheme + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath);
entity.setDownloadPath(mEntity.getDirPath() + "/" + remotePath);
int lastIndex = remotePath.lastIndexOf("/");
String fileName = lastIndex < 0 ? CommonUtil.keyToHashKey(remotePath)

@ -15,10 +15,9 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.AriaManager;
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.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
@ -46,14 +45,12 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
FtpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig<DownloadTaskEntity> downloadInfo) {
super(constance, listener, downloadInfo);
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
mConnectTimeOut = manager.getDownloadConfig().getConnectTimeOut();
mReadTimeOut = manager.getDownloadConfig().getIOTimeOut();
mBufSize = manager.getDownloadConfig().getBuffSize();
isNotNetRetry = manager.getDownloadConfig().isNotNetRetry();
mConnectTimeOut = mAridManager.getDownloadConfig().getConnectTimeOut();
mReadTimeOut = mAridManager.getDownloadConfig().getIOTimeOut();
mBufSize = mAridManager.getDownloadConfig().getBuffSize();
isNotNetRetry = mAridManager.getDownloadConfig().isNotNetRetry();
isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile;
isBlock = STATE.TASK_RECORD.isBlock;
setMaxSpeed(manager.getDownloadConfig().getMaxSpeed());
}
@Override public void run() {
@ -70,7 +67,10 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
String.format("任务【%s】线程__%s__开始下载【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
client = createClient();
if (client == null) return;
if (client == null) {
fail(mChildCurrentLocation, "ftp client 创建失败", null);
return;
}
if (mConfig.START_LOCATION > 0) {
client.setRestartOffset(mConfig.START_LOCATION);
}
@ -168,8 +168,8 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
if (isBreak()) {
break;
}
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(len);
}
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
@ -186,8 +186,6 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
}
}
handleComplete();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} finally {
@ -221,7 +219,9 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
if (isBreak()) {
break;
}
if (mSleepTime > 0) Thread.sleep(mSleepTime);
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(len);
}
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
file.write(buffer, 0, len);
@ -234,8 +234,6 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
}
} catch (IOException e) {
fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
if (file != null) {
@ -246,4 +244,8 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
}
}
}
@Override public int getMaxSpeed() {
return mAridManager.getDownloadConfig().getMaxSpeed();
}
}

@ -15,7 +15,6 @@
*/
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
@ -49,14 +48,12 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
HttpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig<DownloadTaskEntity> downloadInfo) {
super(constance, listener, downloadInfo);
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
mConnectTimeOut = manager.getDownloadConfig().getConnectTimeOut();
mReadTimeOut = manager.getDownloadConfig().getIOTimeOut();
mBufSize = manager.getDownloadConfig().getBuffSize();
isNotNetRetry = manager.getDownloadConfig().isNotNetRetry();
mConnectTimeOut = mAridManager.getDownloadConfig().getConnectTimeOut();
mReadTimeOut = mAridManager.getDownloadConfig().getIOTimeOut();
mBufSize = mAridManager.getDownloadConfig().getBuffSize();
isNotNetRetry = mAridManager.getDownloadConfig().isNotNetRetry();
isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile;
isBlock = STATE.TASK_RECORD.isBlock;
setMaxSpeed(manager.getDownloadConfig().getMaxSpeed());
}
@Override public void run() {
@ -140,8 +137,8 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
if (isBreak()) {
break;
}
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(len);
}
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
@ -158,8 +155,6 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
}
}
handleComplete();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} finally {
@ -186,7 +181,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
* @deprecated 暂时先这样处理无chun
*/
private void readChunk(InputStream is, BufferedRandomAccessFile file)
throws IOException, InterruptedException {
throws IOException {
readNormal(is, file);
}
@ -194,15 +189,15 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
* 读取普通的文件流
*/
private void readNormal(InputStream is, BufferedRandomAccessFile file)
throws IOException, InterruptedException {
throws IOException {
byte[] buffer = new byte[mBufSize];
int len;
while ((len = is.read(buffer)) != -1) {
if (isBreak()) {
break;
}
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(len);
}
file.write(buffer, 0, len);
progress(len);
@ -251,4 +246,8 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
STATE.FAIL_NUM++;
}
}
@Override public int getMaxSpeed() {
return mAridManager.getDownloadConfig().getMaxSpeed();
}
}

@ -77,7 +77,7 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
* 多线程断点续传下载文件开始下载
*/
@Override public void start() {
if (isStop || isCancel){
if (isStop || isCancel) {
return;
}
new Thread(this).start();
@ -87,8 +87,8 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
start();
}
public void setMaxSpeed(double maxSpeed) {
mDownloader.setMaxSpeed(maxSpeed);
@Override public void setMaxSpeed(int speed) {
mDownloader.setMaxSpeed(speed);
}
private void failDownload(String msg, boolean needRetry) {

@ -24,8 +24,6 @@ import com.arialyy.aria.core.download.downloader.AbsGroupUtil;
public abstract class AbsGroupTask<TASK_ENTITY extends AbsGroupTaskEntity>
extends AbsTask<TASK_ENTITY> {
protected AbsGroupUtil mUtil;
@Override public String getKey() {
return mTaskEntity.getEntity().getKey();
}
@ -37,7 +35,7 @@ public abstract class AbsGroupTask<TASK_ENTITY extends AbsGroupTaskEntity>
*/
public void startSubTask(String url) {
if (mUtil != null) {
mUtil.startSubTask(url);
((AbsGroupUtil) mUtil).startSubTask(url);
}
}
@ -48,7 +46,7 @@ public abstract class AbsGroupTask<TASK_ENTITY extends AbsGroupTaskEntity>
*/
public void stopSubTask(String url) {
if (mUtil != null) {
mUtil.stopSubTask(url);
((AbsGroupUtil) mUtil).stopSubTask(url);
}
}
@ -59,7 +57,7 @@ public abstract class AbsGroupTask<TASK_ENTITY extends AbsGroupTaskEntity>
*/
public void cancelSubTask(String url) {
if (mUtil != null) {
mUtil.cancelSubTask(url);
((AbsGroupUtil) mUtil).cancelSubTask(url);
}
}
}

@ -17,6 +17,7 @@ package com.arialyy.aria.core.inf;
import android.content.Context;
import android.os.Handler;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.util.CommonUtil;
/**
@ -38,11 +39,23 @@ public abstract class AbsTask<TASK_ENTITY extends AbsTaskEntity> implements ITas
protected Context mContext;
protected boolean isHeighestTask = false;
private boolean isCancel = false, isStop = false;
protected IUtil mUtil;
public Handler getOutHandler() {
return mOutHandler;
}
/**
* 设置最大下载/上传速度
*
* @param speed 单位为kb
*/
public void setMaxSpeed(int speed) {
if (mUtil != null) {
mUtil.setMaxSpeed(speed);
}
}
/**
* 任务是否完成
*

@ -16,6 +16,7 @@
package com.arialyy.aria.core.inf;
import android.support.annotation.CheckResult;
import java.net.Proxy;
/**
* Created by laoyuyu on 2018/3/9.
@ -45,4 +46,12 @@ public interface IFtpTarget<TARGET extends ITarget> {
*/
@CheckResult
TARGET login(String userName, String password, String account);
/**
* 设置代理
*
* @param proxy {@link Proxy}
*/
@CheckResult
TARGET setProxy(Proxy proxy);
}

@ -22,6 +22,8 @@ import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.pool.BaseCachePool;
import com.arialyy.aria.core.queue.pool.BaseExecutePool;
import com.arialyy.aria.util.ALog;
import java.util.Map;
import java.util.Set;
/**
* Created by lyy on 2017/2/23.
@ -80,6 +82,18 @@ abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEnt
}
}
/**
* 最大下载速度
*/
public void setMaxSpeed(int maxSpeed) {
Map<String, TASK> tasks = mExecutePool.getAllTask();
Set<String> keys = tasks.keySet();
for (String key : keys) {
TASK task = tasks.get(key);
task.setMaxSpeed(maxSpeed);
}
}
/**
* 获取配置文件配置的最大可执行任务数
*/

@ -104,18 +104,6 @@ public class DownloadTaskQueue extends AbsTaskQueue<DownloadTask, DownloadTaskEn
}
}
/**
* 最大下载速度
*/
public void setMaxSpeed(double maxSpeed) {
Map<String, DownloadTask> tasks = mExecutePool.getAllTask();
Set<String> keys = tasks.keySet();
for (String key : keys) {
DownloadTask task = tasks.get(key);
task.setMaxSpeed(maxSpeed);
}
}
@Override public DownloadTask createTask(String target, DownloadTaskEntity entity) {
DownloadTask task = null;
if (!TextUtils.isEmpty(target)) {

@ -17,11 +17,14 @@ package com.arialyy.aria.core.upload;
import android.support.annotation.CheckResult;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.common.ftp.FTPSConfig;
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;
import java.net.Proxy;
/**
* Created by Aria.Lao on 2017/7/27.
@ -62,7 +65,16 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
if (!b) {
return false;
}
mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(mTempUrl));
FtpUrlEntity temp = mTaskEntity.getUrlEntity();
FtpUrlEntity newEntity = CommonUtil.getFtpUrlInfo(mTempUrl);
if (temp != null) { //处理FTPS的信息
newEntity.isFtps = temp.isFtps;
newEntity.storePass = temp.storePass;
newEntity.keyAlias = temp.keyAlias;
newEntity.protocol = temp.protocol;
newEntity.storePath = temp.storePath;
}
mTaskEntity.setUrlEntity(newEntity);
mTaskEntity.getUrlEntity().account = mAccount;
mTaskEntity.getUrlEntity().user = mUser;
mTaskEntity.getUrlEntity().password = mPw;
@ -70,6 +82,21 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
return true;
}
/**
* 是否是FTPS协议
* 如果是FTPS协议需要使用{@link FTPSConfig#setStorePath(String)} {@link FTPSConfig#setAlias(String)}
* 设置证书信息
*/
@CheckResult
public FTPSConfig<FtpUploadTarget> asFtps() {
if (mTaskEntity.getUrlEntity() == null) {
FtpUrlEntity urlEntity = new FtpUrlEntity();
urlEntity.isFtps = true;
mTaskEntity.setUrlEntity(urlEntity);
}
return new FTPSConfig<>(this);
}
@CheckResult
@Override public FtpUploadTarget charSet(String charSet) {
return mDelegate.charSet(charSet);
@ -89,4 +116,8 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
mAccount = account;
return this;
}
@Override public FtpUploadTarget setProxy(Proxy proxy) {
return mDelegate.setProxy(proxy);
}
}

@ -40,6 +40,16 @@ import java.util.Set;
public class UploadReceiver extends AbsReceiver {
private static final String TAG = "UploadReceiver";
/**
* 设置最大上传速度单位kb
*
* @param maxSpeed 为0表示不限速
*/
public UploadReceiver setMaxSpeed(int maxSpeed) {
AriaManager.getInstance(AriaManager.APP).getUploadConfig().setMaxSpeed(maxSpeed);
return this;
}
/**
* 加载HTTP单文件上传任务
*

@ -15,10 +15,9 @@
*/
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.AriaManager;
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.common.ftp.AbsFtpThreadTask;
import com.arialyy.aria.core.inf.IEventListener;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
@ -41,11 +40,14 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
FtpThreadTask(StateConstance constance, IEventListener listener,
SubThreadConfig<UploadTaskEntity> info) {
super(constance, listener, info);
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
mConnectTimeOut = manager.getUploadConfig().getConnectTimeOut();
mReadTimeOut = manager.getUploadConfig().getIOTimeOut();
mBufSize = manager.getUploadConfig().getBuffSize();
isNotNetRetry = manager.getUploadConfig().isNotNetRetry();
mConnectTimeOut = mAridManager.getUploadConfig().getConnectTimeOut();
mReadTimeOut = mAridManager.getUploadConfig().getIOTimeOut();
mBufSize = mAridManager.getUploadConfig().getBuffSize();
isNotNetRetry = mAridManager.getUploadConfig().isNotNetRetry();
}
@Override public int getMaxSpeed() {
return mAridManager.getUploadConfig().getMaxSpeed();
}
@Override public void run() {
@ -128,15 +130,18 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
int bytesTransferred, long streamSize) {
if (isBreak() && !isStoped) {
try {
try {
if (isBreak() && !isStoped) {
isStoped = true;
client.abor();
} catch (IOException e) {
e.printStackTrace();
}
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(bytesTransferred);
}
progress(bytesTransferred);
} catch (IOException e) {
e.printStackTrace();
}
progress(bytesTransferred);
}
});
} catch (IOException e) {

@ -15,7 +15,6 @@
*/
package com.arialyy.aria.core.upload.uploader;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsThreadTask;
import com.arialyy.aria.core.common.StateConstance;
import com.arialyy.aria.core.common.SubThreadConfig;
@ -52,11 +51,10 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
HttpThreadTask(StateConstance constance, IUploadListener listener,
SubThreadConfig<UploadTaskEntity> uploadInfo) {
super(constance, listener, uploadInfo);
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
mConnectTimeOut = manager.getUploadConfig().getConnectTimeOut();
mReadTimeOut = manager.getUploadConfig().getIOTimeOut();
mBufSize = manager.getUploadConfig().getBuffSize();
isNotNetRetry = manager.getUploadConfig().isNotNetRetry();
mConnectTimeOut = mAridManager.getUploadConfig().getConnectTimeOut();
mReadTimeOut = mAridManager.getUploadConfig().getIOTimeOut();
mBufSize = mAridManager.getUploadConfig().getBuffSize();
isNotNetRetry = mAridManager.getUploadConfig().isNotNetRetry();
}
@Override public void run() {
@ -167,6 +165,9 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
if (STATE.isCancel) {
break;
}
if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(bytesRead);
}
}
mOutputStream.flush();
@ -212,4 +213,8 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mOutputStream.close();
return response.toString();
}
@Override public int getMaxSpeed() {
return mAridManager.getUploadConfig().getMaxSpeed();
}
}

@ -99,7 +99,7 @@ public class SimpleUploadUtil implements IUtil, Runnable {
mUploader.cancel();
}
@Override public void setMaxSpeed(double maxSpeed) {
mUploader.setMaxSpeed(maxSpeed);
@Override public void setMaxSpeed(int speed) {
mUploader.setMaxSpeed(speed);
}
}

@ -289,6 +289,7 @@ public class CommonUtil {
entity.user = userInfo;
}
}
entity.scheme = uri.getScheme();
entity.remotePath = TextUtils.isEmpty(remotePath) ? "/" : remotePath;
return entity;
}
@ -395,6 +396,23 @@ public class CommonUtil {
return md5;
}
/**
* 获取字符串的md5
*
* @return 字符串为空或获取md5失败则返回""
*/
public static String getStrMd5(String str) {
if (TextUtils.isEmpty(str)) return "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
return new BigInteger(1, md.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
ALog.e(TAG, e.getMessage());
}
return "";
}
/**
* 删除任务组记录
*

@ -17,6 +17,7 @@ package com.arialyy.aria.util;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.ProtocolType;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -30,6 +31,8 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.WeakHashMap;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@ -44,18 +47,26 @@ import javax.net.ssl.X509TrustManager;
*/
public class SSLContextUtil {
private static final String TAG = "SSLContextUtil";
private static Map<String, SSLContext> SSL_CACHE = new WeakHashMap<>();
/**
* 从assets目录下加载证书
*
* @param caAlias CA证书别名
* @param caPath 保存在assets目录下的CA证书完整路径
* @param protocol 连接协议
*/
public static SSLContext getSSLContextFromAssets(String caAlias, String caPath) {
public static SSLContext getSSLContextFromAssets(String caAlias, String caPath,
@ProtocolType String protocol) {
try {
String cacheKey = getCacheKey(caAlias, caPath);
SSLContext sslContext = SSL_CACHE.get(cacheKey);
if (sslContext != null) {
return sslContext;
}
InputStream caInput = AriaManager.APP.getAssets().open(caPath);
Certificate ca = loadCert(caInput);
return createContext(caAlias, ca);
return createContext(caAlias, ca, protocol, cacheKey);
} catch (IOException | CertificateException e) {
e.printStackTrace();
}
@ -67,21 +78,32 @@ public class SSLContextUtil {
*
* @param caAlias CA证书别名
* @param caPath CA证书路径
* @param protocol 连接协议
*/
public static SSLContext getSSLContext(String caAlias, String caPath) {
public static SSLContext getSSLContext(String caAlias, String caPath,
@ProtocolType String protocol) {
if (TextUtils.isEmpty(caAlias) || TextUtils.isEmpty(caPath)) {
return null;
}
try {
String cacheKey = getCacheKey(caAlias, caPath);
SSLContext sslContext = SSL_CACHE.get(cacheKey);
if (sslContext != null) {
return sslContext;
}
Certificate ca = loadCert(new FileInputStream(caPath));
return createContext(caAlias, ca);
return createContext(caAlias, ca, protocol, cacheKey);
} catch (CertificateException | IOException e) {
e.printStackTrace();
}
return null;
}
private static SSLContext createContext(String caAlias, Certificate ca) {
/**
* @param cacheKey 别名 + 证书路径然后取md5
*/
private static SSLContext createContext(String caAlias, Certificate ca,
@ProtocolType String protocol, String cacheKey) {
try {
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
@ -97,8 +119,10 @@ public class SSLContextUtil {
kmf.init(keyStore, null);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
SSLContext context =
SSLContext.getInstance(TextUtils.isEmpty(protocol) ? ProtocolType.Default : protocol);
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
SSL_CACHE.put(cacheKey, context);
return context;
} catch (CertificateException | NoSuchAlgorithmException | IOException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
e.printStackTrace();
@ -106,6 +130,10 @@ public class SSLContextUtil {
return null;
}
private static String getCacheKey(String alias, String path) {
return CommonUtil.getStrMd5(String.format("%s_%s", alias, path));
}
/**
* 加载CA证书
*
@ -123,10 +151,11 @@ public class SSLContextUtil {
/**
* 服务器证书不是由 CA 签署的而是自签署时获取默认的SSL
*/
public static SSLContext getDefaultSLLContext() {
public static SSLContext getDefaultSLLContext(@ProtocolType String protocol) {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
sslContext =
SSLContext.getInstance(TextUtils.isEmpty(protocol) ? ProtocolType.Default : protocol);
sslContext.init(null, new TrustManager[] { trustManagers }, new SecureRandom());
} catch (Exception e) {
e.printStackTrace();

@ -3,6 +3,7 @@
- 组合任务新增`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]()
- 增加速度限制支持[see]()
+ v_3.4.7
- 修复分块任务异常操作导致的问题
+ v_3.4.6

@ -13,13 +13,13 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<!--android:name=".test.TestActivity"-->
<!--android:name=".test.TestGroupActivity"-->
<!--android:name=".MainActivity"-->
<!--android:name="com.arialyy.simple.test.AnyRunActivity"-->
<!--android:name=".download.group.DownloadGroupActivity"-->
<!--android:name=".test.AnyRunActivity"-->
<!--android:name=".test.TestFTPDirActivity"-->
<!--android:name=".test.TestFTPActivity"-->
<activity
android:name=".test.AnyRunActivity"
android:name=".download.SingleTaskActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@ -29,7 +29,7 @@
</activity>
<activity android:name=".download.DownloadActivity"/>
<activity android:name=".download.SingleTaskActivity"/>
<!--<activity android:name=".download.SingleTaskActivity"/>-->
<activity android:name=".download.multi_download.MultiTaskActivity"/>
<activity android:name=".download.fragment_download.FragmentActivity"/>
<activity android:name=".download.multi_download.MultiDownloadActivity"/>

@ -11,6 +11,10 @@
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
<download>
<!--设置任务最大下载速度,0表示不限速,单位为:kb-->
<maxSpeed value="0"/>
<!--
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用
注意:
@ -66,7 +70,8 @@
</download>
<upload>
<!--设置任务最大上传速度,0表示不限速,单位为:kb-->
<maxSpeed value="0"/>
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
<notNetRetry value="false"/>

@ -19,12 +19,12 @@ import java.io.File;
* Created by Administrator on 2018/4/12.
*/
public class TestActivity extends BaseActivity<ActivityTestBinding> {
String TAG = "TestActivity";
public class TestFTPActivity extends BaseActivity<ActivityTestBinding> {
String TAG = "TestFTPActivity";
//String URL = "http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
//private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
private final String URL = "ftp://192.168.1.2:21/aa//你好";
private final String FILE_PATH = "/mnt/sdcard/mmm.mp4";
private final String URL = "ftps://192.168.29.140:990/aa/你好";
@Override protected int setLayoutId() {
@ -35,7 +35,7 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
super.init(savedInstanceState);
mBar.setVisibility(View.GONE);
Aria.upload(this).register();
Aria.upload(this).setMaxSpeed(128);
}
@Upload.onWait void onWait(UploadTask task) {
@ -51,7 +51,7 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
}
@Upload.onTaskRunning protected void running(UploadTask task) {
Log.d(TAG, "running");
Log.d(TAG, "running,speed=" + task.getConvertSpeed());
}
@Upload.onTaskResume void taskResume(UploadTask task) {
@ -82,6 +82,10 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
.login("lao", "123456")
.setUploadUrl(URL)
.setExtendField("韩寒哈大双")
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
.setStorePass("123456")
.start();
//Uri uri = Uri.parse("ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv");
//ALog.d(TAG, "sh = " + uri.getScheme() + ", user = " + uri.getUserInfo() + ", host = " + uri.getHost() + ", port = " + uri.getPort() + " remotePath = " + uri.getPath());

@ -17,9 +17,9 @@ import java.util.List;
* Created by Administrator on 2018/4/12.
*/
public class TestGroupActivity extends BaseActivity<ActivityTestBinding> {
public class TestFTPDirActivity extends BaseActivity<ActivityTestBinding> {
List<String> mUrls;
private static final String dir = "ftp://192.168.1.8:21/upload/测试";
private static final String dir = "ftps://192.168.29.140:990/upload/测试";
@Override protected int setLayoutId() {
return R.layout.activity_test;
@ -87,6 +87,10 @@ public class TestGroupActivity extends BaseActivity<ActivityTestBinding> {
.setGroupAlias("ftp文件夹下载")
//.setSubTaskFileName(getModule(GroupModule.class).getSubName())
.login("lao", "123456")
.asFtps()
.setStorePath("/mnt/sdcard/Download/server.crt")
.setAlias("www.laoyuyu.me")
.setStorePass("123456")
.start();
break;
case R.id.stop:

@ -17,6 +17,7 @@ package com.arialyy.aria.core;
import android.text.TextUtils;
import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.util.ALog;
@ -247,6 +248,21 @@ class Configuration {
*/
int iOTimeOut = 20 * 1000;
/**
* 设置最大下载/上传速度单位kb, 为0表示不限速
*/
int maxSpeed = 0;
public int getMaxSpeed() {
return maxSpeed;
}
public BaseTaskConfig setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
saveKey("maxSpeed", String.valueOf(maxSpeed));
return this;
}
public long getUpdateInterval() {
return updateInterval;
}
@ -374,11 +390,6 @@ class Configuration {
*/
int threadNum = 3;
/**
* 设置最大下载速度单位kb, 为0表示不限速
*/
int maxSpeed = 0;
/**
* 多线程下载是否使用块下载模式{@code true}使用{@code false}不使用
* 注意
@ -393,6 +404,13 @@ class Configuration {
return useBlock;
}
@Override public DownloadConfig setMaxSpeed(int maxSpeed) {
super.setMaxSpeed(maxSpeed);
DownloadTaskQueue.getInstance().setMaxSpeed(maxSpeed);
DownloadGroupTaskQueue.getInstance().setMaxSpeed(maxSpeed);
return this;
}
public DownloadConfig setUseBlock(boolean useBlock) {
this.useBlock = useBlock;
saveKey("useBlock", String.valueOf(useBlock));
@ -407,17 +425,6 @@ class Configuration {
return this;
}
public int getMaxSpeed() {
return maxSpeed;
}
public DownloadConfig setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
saveKey("maxSpeed", String.valueOf(maxSpeed));
DownloadTaskQueue.getInstance().setMaxSpeed(maxSpeed);
return this;
}
public DownloadConfig setThreadNum(int threadNum) {
this.threadNum = threadNum;
saveKey("threadNum", String.valueOf(threadNum));
@ -478,6 +485,12 @@ class Configuration {
loadConfig();
}
@Override public UploadConfig setMaxSpeed(int maxSpeed) {
super.setMaxSpeed(maxSpeed);
UploadTaskQueue.getInstance().setMaxSpeed(maxSpeed);
return this;
}
public UploadConfig setMaxTaskNum(int maxTaskNum) {
oldMaxTaskNum = this.maxTaskNum;
this.maxTaskNum = maxTaskNum;

@ -29,7 +29,6 @@ import com.arialyy.aria.util.ALog;
public class UploadTask extends AbsNormalTask<UploadTaskEntity> {
private static final String TAG = "UploadTask";
private SimpleUploadUtil mUtil;
private BaseUListener<UploadEntity, UploadTaskEntity, UploadTask> mListener;
private UploadTask(UploadTaskEntity taskEntity, Handler outHandler) {

Loading…
Cancel
Save