修复某些服务器range 返回不了长度的bug

Change-Id: I4a239898bdf0926c6ef2ad58e3fde51e06dd597d
This commit is contained in:
laoyuyu
2018-03-13 17:26:00 +08:00
parent 50ed36a470
commit 402086d7dd
15 changed files with 126 additions and 92 deletions

View File

@@ -31,16 +31,18 @@ public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_
private static final String TAG = "FtpDelegate";
private ENTITY mEntity;
private TASK_ENTITY mTaskEntity;
private TARGET mTarget;
public FtpDelegate(TASK_ENTITY mTaskEntity) {
this.mTaskEntity = mTaskEntity;
public FtpDelegate(TARGET target, TASK_ENTITY taskEntity) {
mTarget = target;
mTaskEntity = taskEntity;
mEntity = mTaskEntity.getEntity();
}
@Override public TARGET charSet(String charSet) {
if (TextUtils.isEmpty(charSet)) return (TARGET) this;
if (TextUtils.isEmpty(charSet)) return mTarget;
mTaskEntity.charSet = charSet;
return (TARGET) this;
return mTarget;
}
@Override public TARGET login(String userName, String password) {
@@ -50,15 +52,15 @@ public class FtpDelegate<TARGET extends ITarget, ENTITY extends AbsEntity, TASK_
@Override public TARGET login(String userName, String password, String account) {
if (TextUtils.isEmpty(userName)) {
ALog.e(TAG, "用户名不能为null");
return (TARGET) this;
return mTarget;
} else if (TextUtils.isEmpty(password)) {
ALog.e(TAG, "密码不能为null");
return (TARGET) this;
return mTarget;
}
mTaskEntity.urlEntity.needLogin = true;
mTaskEntity.urlEntity.user = userName;
mTaskEntity.urlEntity.password = password;
mTaskEntity.urlEntity.account = account;
return (TARGET) this;
return mTarget;
}
}

View File

@@ -37,9 +37,12 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
private static final String TAG = "HttpHeaderDelegate";
private ENTITY mEntity;
private TASK_ENTITY mTaskEntity;
private TARGET mTarget;
public HttpHeaderDelegate(TARGET target, TASK_ENTITY taskEntity) {
mTarget = target;
mTaskEntity = taskEntity;
public HttpHeaderDelegate(TASK_ENTITY mTaskEntity) {
this.mTaskEntity = mTaskEntity;
mEntity = mTaskEntity.getEntity();
}
@@ -54,10 +57,10 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
public TARGET addHeader(@NonNull String key, @NonNull String value) {
if (TextUtils.isEmpty(key)) {
ALog.w(TAG, "设置header失败header对应的key不能为null");
return (TARGET) this;
return mTarget;
} else if (TextUtils.isEmpty(value)) {
ALog.w(TAG, "设置header失败header对应的value不能为null");
return (TARGET) this;
return mTarget;
}
if (mTaskEntity.headers.get(key) == null) {
mTaskEntity.headers.put(key, value);
@@ -66,7 +69,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
mTaskEntity.headers.put(key, value);
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
/**
@@ -79,7 +82,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
public TARGET addHeaders(@NonNull Map<String, String> headers) {
if (headers.size() == 0) {
ALog.w(TAG, "设置header失败map没有header数据");
return (TARGET) this;
return mTarget;
}
/*
两个map比较逻辑
@@ -123,7 +126,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
/**
@@ -135,7 +138,7 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
@Override
public TARGET setRequestMode(RequestEnum requestEnum) {
mTaskEntity.requestEnum = requestEnum;
return (TARGET) this;
return mTarget;
}
/**
@@ -145,12 +148,12 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/
@Override
public TARGET setHeaderMd5Key(String md5Key) {
if (TextUtils.isEmpty(md5Key)) return (TARGET) this;
if (TextUtils.isEmpty(md5Key)) return mTarget;
mTaskEntity.md5Key = md5Key;
if (TextUtils.isEmpty(mTaskEntity.md5Key) || !mTaskEntity.md5Key.equals(md5Key)) {
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
/**
@@ -159,13 +162,13 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/
@Override
public TARGET setHeaderContentLengthKey(String contentLength) {
if (TextUtils.isEmpty(contentLength)) return (TARGET) this;
if (TextUtils.isEmpty(contentLength)) return mTarget;
mTaskEntity.contentLength = contentLength;
if (TextUtils.isEmpty(mTaskEntity.contentLength) || !mTaskEntity.contentLength.equals(
contentLength)) {
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
/**
@@ -175,13 +178,13 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/
@Override
public TARGET setHeaderDispositionKey(String dispositionKey) {
if (TextUtils.isEmpty(dispositionKey)) return (TARGET) this;
if (TextUtils.isEmpty(dispositionKey)) return mTarget;
mTaskEntity.dispositionKey = dispositionKey;
if (TextUtils.isEmpty(mTaskEntity.dispositionKey) || !mTaskEntity.dispositionKey.equals(
dispositionKey)) {
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
/**
@@ -191,12 +194,12 @@ public class HttpHeaderDelegate<TARGET extends ITarget, ENTITY extends AbsEntity
*/
@Override
public TARGET setHeaderDispositionFileKey(String dispositionFileKey) {
if (TextUtils.isEmpty(dispositionFileKey)) return (TARGET) this;
if (TextUtils.isEmpty(dispositionFileKey)) return mTarget;
mTaskEntity.dispositionFileKey = dispositionFileKey;
if (TextUtils.isEmpty(mTaskEntity.dispositionFileKey) || !mTaskEntity.dispositionFileKey.equals(
dispositionFileKey)) {
mTaskEntity.update();
}
return (TARGET) this;
return mTarget;
}
}

View File

@@ -49,7 +49,7 @@ public class DownloadTarget extends BaseNormalTarget<DownloadTarget>
}
private void initTHis() {
mDelegate = new HttpHeaderDelegate<>(mTaskEntity);
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
}
/**

View File

@@ -45,7 +45,7 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
mTaskEntity.requestType = AbsTaskEntity.D_FTP_DIR;
mEntity = mTaskEntity.entity;
mDelegate = new FtpDelegate<>(mTaskEntity);
mDelegate = new FtpDelegate<>(this, mTaskEntity);
}
@Override protected int getTargetType() {

View File

@@ -51,7 +51,7 @@ public class FtpDownloadTarget extends BaseNormalTarget<FtpDownloadTarget>
mTaskEntity.refreshInfo = refreshInfo;
mTaskEntity.requestType = AbsTaskEntity.D_FTP;
mDelegate = new FtpDelegate<>(mTaskEntity);
mDelegate = new FtpDelegate<>(this, mTaskEntity);
}
/**

View File

@@ -15,6 +15,7 @@
*/
package com.arialyy.aria.core.download.downloader;
import android.util.Log;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException;
@@ -80,28 +81,28 @@ class ConnectionHelp {
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
}
if (keys == null || !keys.contains("Accept")) {
StringBuilder accept = new StringBuilder();
accept.append("image/gif, ")
.append("image/jpeg, ")
.append("image/pjpeg, ")
.append("image/webp, ")
.append("image/apng, ")
.append("application/xml, ")
.append("application/xaml+xml, ")
.append("application/xhtml+xml, ")
.append("application/x-shockwave-flash, ")
.append("application/x-ms-xbap, ")
.append("application/x-ms-application, ")
.append("application/msword, ")
.append("application/vnd.ms-excel, ")
.append("application/vnd.ms-xpsdocument, ")
.append("application/vnd.ms-powerpoint, ")
.append("text/plain, ")
.append("text/html, ")
.append("*/*");
conn.setRequestProperty("Accept", accept.toString());
}
//if (keys == null || !keys.contains("Accept")) {
// StringBuilder accept = new StringBuilder();
// accept.append("image/gif, ")
// .append("image/jpeg, ")
// .append("image/pjpeg, ")
// .append("image/webp, ")
// .append("image/apng, ")
// .append("application/xml, ")
// .append("application/xaml+xml, ")
// .append("application/xhtml+xml, ")
// .append("application/x-shockwave-flash, ")
// .append("application/x-ms-xbap, ")
// .append("application/x-ms-application, ")
// .append("application/msword, ")
// .append("application/vnd.ms-excel, ")
// .append("application/vnd.ms-xpsdocument, ")
// .append("application/vnd.ms-powerpoint, ")
// .append("text/plain, ")
// .append("text/html, ")
// .append("*/*");
// conn.setRequestProperty("Accept", accept.toString());
//}
if (keys == null || !keys.contains("Accept-Encoding")) {
conn.setRequestProperty("Accept-Encoding", "identity");
}

View File

@@ -15,7 +15,9 @@
*/
package com.arialyy.aria.core.download.downloader;
import android.location.Address;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
@@ -27,7 +29,9 @@ import com.arialyy.aria.util.CommonUtil;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
@@ -58,10 +62,7 @@ class HttpFileInfoThread implements Runnable {
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut);
conn.setRequestMethod(mTaskEntity.requestEnum.name);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setChunkedStreamingMode(0);
//conn.setChunkedStreamingMode(0);
conn.connect();
handleConnect(conn);
} catch (IOException e) {
@@ -83,6 +84,17 @@ class HttpFileInfoThread implements Runnable {
if (len < 0) {
String temp = conn.getHeaderField(mTaskEntity.contentLength);
len = TextUtils.isEmpty(temp) ? -1 : Long.parseLong(temp);
// 某些服务如果设置了conn.setRequestProperty("Range", "bytes=" + 0 + "-");
// 会返回 Content-Range: bytes 0-225427911/225427913
if (len < 0){
temp = conn.getHeaderField("Content-Range");
if (TextUtils.isEmpty(temp)){
len = -1;
}else {
int start = temp.indexOf("/");
len = Long.parseLong(temp.substring(start + 1, temp.length()));
}
}
}
int code = conn.getResponseCode();
boolean isComplete = false;
@@ -90,20 +102,22 @@ class HttpFileInfoThread implements Runnable {
String md5Code = conn.getHeaderField(mTaskEntity.md5Key);
mEntity.setMd5Code(md5Code);
}
String disposition = conn.getHeaderField(mTaskEntity.dispositionKey);
Map<String, List<String>> headers = conn.getHeaderFields();
boolean isChunked = false;
//https://my.oschina.net/ososchina/blog/666761
if (conn.getHeaderField("Transfer-Encoding").equals("chunked")) {
final String str = conn.getHeaderField("Transfer-Encoding");
if (!TextUtils.isEmpty(str) && str.equals("chunked")) {
isChunked = true;
StringBuffer sb = new StringBuffer();
byte[] buffer = new byte[1024];
InputStream is = conn.getInputStream();
int l = 0;
//StringBuffer sb = new StringBuffer();
//byte[] buffer = new byte[1024];
//InputStream is = conn.getInputStream();
//int l = 0;
//while (true){
// is.read()
//}
}
String disposition = conn.getHeaderField(mTaskEntity.dispositionKey);
if (!TextUtils.isEmpty(disposition)) {
mEntity.setDisposition(CommonUtil.encryptBASE64(disposition));
if (disposition.contains(mTaskEntity.dispositionFileKey)) {

View File

@@ -90,28 +90,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
if (STATE.isCancel || STATE.isStop) {
return;
}
//支持断点的处理
if (mConfig.SUPPORT_BP) {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕");
writeConfig(true, 1);
STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) {
File configFile = new File(mConfigFPath);
if (configFile.exists()) {
configFile.delete();
}
STATE.isRunning = false;
mListener.onComplete();
}
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false);
}
} else {
ALog.i(TAG, "任务下载完成");
STATE.isRunning = false;
mListener.onComplete();
}
handleStop();
} catch (MalformedURLException e) {
fail(mChildCurrentLocation, "下载链接异常", e);
} catch (IOException e) {
@@ -140,7 +119,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
*/
private void readChunk(InputStream is, RandomAccessFile file)
throws IOException, InterruptedException {
}
/**
@@ -162,6 +141,40 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
}
}
/**
* 处理暂停或完成配置文件的更新或事件回调
*
* @throws IOException
*/
private void handleStop() throws IOException {
//支持断点的处理
if (mConfig.SUPPORT_BP) {
if (mChildCurrentLocation == mConfig.END_LOCATION) {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕");
writeConfig(true, 1);
STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) {
File configFile = new File(mConfigFPath);
if (configFile.exists()) {
configFile.delete();
}
STATE.isRunning = false;
mListener.onComplete();
}
} else {
STATE.FAIL_NUM++;
}
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false);
}
} else {
ALog.i(TAG, "任务下载完成");
STATE.isRunning = false;
mListener.onComplete();
}
}
@Override protected String getTaskType() {
return "HTTP_DOWNLOAD";
}

View File

@@ -19,7 +19,6 @@ package com.arialyy.aria.core.inf;
* Created by AriaL on 2017/6/29.
*/
public interface ITarget<TARGET extends ITarget> {
/**
* 获取任务状态
*

View File

@@ -21,10 +21,8 @@ import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.delegate.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.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
/**
* Created by Aria.Lao on 2017/7/27.
@@ -43,7 +41,7 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
private void initTask(String filePath) {
initTarget(filePath);
mTaskEntity.requestType = AbsTaskEntity.U_FTP;
mDelegate = new FtpDelegate<>(mTaskEntity);
mDelegate = new FtpDelegate<>(this, mTaskEntity);
}
/**

View File

@@ -43,7 +43,7 @@ public class UploadTarget extends BaseNormalTarget<UploadTarget>
//http暂时不支持断点上传
mTaskEntity.isSupportBP = false;
mTaskEntity.requestType = AbsTaskEntity.U_HTTP;
mDelegate = new HttpHeaderDelegate<>(mTaskEntity);
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
}
@Override public UploadTarget setUploadUrl(@NonNull String uploadUrl) {

View File

@@ -29,7 +29,8 @@ import org.apache.commons.net.ftp.FTPFile;
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @since 3.1
*/
public class MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
public class
MacOsPeterFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
static final String DEFAULT_DATE_FORMAT = "MMM d yyyy"; //Nov 9 2001

View File

@@ -1,6 +1,7 @@
## 开发日志
+ v_3.3.16
- 修复一个activity启动多次无法进行回掉的bug https://github.com/AriaLyy/Aria/issues/200
- 优化target代码结构
+ v_3.3.14
- 修复ftp上传和下载的兼容性问题
- 如果url中的path有"//"将替换为"/"

View File

@@ -5,13 +5,13 @@
<download>
<!--设置下载线程线程下载数改变后新的下载任务才会生效如果任务大小小于1m该设置也不会生效-->
<threadNum value="3"/>
<threadNum value="1"/>
<!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="2"/>
<!--设置下载失败重试次数默认为10-->
<reTryNum value="2"/>
<reTryNum value="1"/>
<!--设置重试间隔单位为毫秒默认2000毫秒-->
<reTryInterval value="5000"/>

View File

@@ -29,6 +29,7 @@ import android.widget.Toast;
import butterknife.Bind;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
@@ -61,8 +62,9 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//"http://qudao.5535.cn/one/game.html?game=531&cpsuser=xiaoeryu2";
//"https://bogoe-res.mytbz.com/tbzengsong/If You're Happy.mp3";
//"http://ozr0ucjs5.bkt.clouddn.com/51_box-104_20180131202610.apk";
"http://kf.lyfz.net/api/v1/we_chat/Business/getMaterial?company_id=51454009d703c86c91353f61011ecf2f&appid=wx88c6052d06eaaf7d&media_id=qpkQb72KqNkZhBNIUw7asF0LuJouXCTBd3A-rS2bYl7H4kvTZstEXD3F-pDVeqA-&type=3";
//"http://kf.lyfz.net/api/v1/we_chat/Business/getMaterial?company_id=51454009d703c86c91353f61011ecf2f&appid=wx88c6052d06eaaf7d&media_id=qpkQb72KqNkZhBNIUw7asF0LuJouXCTBd3A-rS2bYl7H4kvTZstEXD3F-pDVeqA-&type=3";
//"https://www.baidu.com/link?url=_LFCuTPtnzFxVJByJ504QymRywIA1Z_T5xUxe9ZLuxcGM0C_RcdpWyB1eGjbJC-e5wv5wAKM4WmLMAS5KeF6EZJHB8Va3YqZUiaErqK_pxm&wd=&eqid=e8583fe70002d126000000065a99f864";
"http://58.210.9.131/tpk/sipgt/TDLYZTGH.tpk";
@Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop;
@Bind(R.id.cancel) Button mCancel;
@@ -230,8 +232,8 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("DNT", "1")
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
//.setRequestMode(RequestEnum.POST)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk")
.setRequestMode(RequestEnum.GET)
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk")
.resetState()
.start();
//.add();