parent
49ccc1b28a
commit
16e76b42ed
@ -1,41 +0,0 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import com.arialyy.aria.core.common.AbsNormalEntity; |
||||
import com.arialyy.aria.core.common.SubThreadConfig; |
||||
import com.arialyy.aria.core.task.AbsThreadTaskAdapter; |
||||
|
||||
/** |
||||
* @author lyy |
||||
* Date: 2019-09-22 |
||||
*/ |
||||
public abstract class BaseHttpThreadTaskAdapter extends AbsThreadTaskAdapter { |
||||
protected HttpTaskOption mTaskOption; |
||||
|
||||
protected BaseHttpThreadTaskAdapter(SubThreadConfig config) { |
||||
super(config); |
||||
mTaskOption = (HttpTaskOption) getTaskWrapper().getTaskOption(); |
||||
} |
||||
|
||||
protected String getFileName() { |
||||
return getEntity().getFileName(); |
||||
} |
||||
|
||||
protected AbsNormalEntity getEntity() { |
||||
return (AbsNormalEntity) getTaskWrapper().getEntity(); |
||||
} |
||||
} |
@ -1,184 +0,0 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.AriaConfig; |
||||
import com.arialyy.aria.core.ProtocolType; |
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import com.arialyy.aria.util.SSLContextUtil; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.net.CookieManager; |
||||
import java.net.CookieStore; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.MalformedURLException; |
||||
import java.net.URL; |
||||
import java.net.URLConnection; |
||||
import java.net.URLEncoder; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
import java.util.zip.GZIPInputStream; |
||||
import java.util.zip.InflaterInputStream; |
||||
import javax.net.ssl.HttpsURLConnection; |
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLSocketFactory; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/1/18. 链接帮助类 |
||||
*/ |
||||
public final class ConnectionHelp { |
||||
private static final String TAG = "ConnectionHelp"; |
||||
|
||||
/** |
||||
* 处理url参数 |
||||
*/ |
||||
public static URL handleUrl(String url, HttpOption option) |
||||
throws MalformedURLException { |
||||
Map<String, String> params = option.getParams(); |
||||
if (params.isEmpty()) { |
||||
return new URL(CommonUtil.convertUrl(url)); |
||||
} |
||||
|
||||
if (option.getRequestMethod() == RequestEnum.GET) { |
||||
if (!url.contains("?")) { |
||||
url = url.concat("?"); |
||||
} |
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.append(url).append("?"); |
||||
Set<String> keys = params.keySet(); |
||||
for (String key : keys) { |
||||
sb.append(URLEncoder.encode(key)) |
||||
.append("=") |
||||
.append(URLEncoder.encode(params.get(key))) |
||||
.append("&"); |
||||
} |
||||
String temp = sb.toString(); |
||||
temp = temp.substring(0, temp.length() - 1); |
||||
return new URL(CommonUtil.convertUrl(temp)); |
||||
} |
||||
|
||||
if (option.getRequestMethod() == RequestEnum.POST) { |
||||
|
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 处理链接 |
||||
* |
||||
* @throws IOException |
||||
*/ |
||||
public static HttpURLConnection handleConnection(URL url, HttpTaskOption taskDelegate) |
||||
throws IOException { |
||||
HttpURLConnection conn; |
||||
URLConnection urlConn; |
||||
if (taskDelegate.getProxy() != null) { |
||||
urlConn = url.openConnection(taskDelegate.getProxy()); |
||||
} else { |
||||
urlConn = url.openConnection(); |
||||
} |
||||
if (urlConn instanceof HttpsURLConnection) { |
||||
AriaConfig config = AriaConfig.getInstance(); |
||||
conn = (HttpsURLConnection) urlConn; |
||||
SSLContext sslContext = |
||||
SSLContextUtil.getSSLContextFromAssets(config.getDConfig().getCaName(), |
||||
config.getDConfig().getCaPath(), ProtocolType.Default); |
||||
if (sslContext == null) { |
||||
sslContext = SSLContextUtil.getDefaultSLLContext(ProtocolType.Default); |
||||
} |
||||
SSLSocketFactory ssf = sslContext.getSocketFactory(); |
||||
((HttpsURLConnection) conn).setSSLSocketFactory(ssf); |
||||
((HttpsURLConnection) conn).setHostnameVerifier(SSLContextUtil.HOSTNAME_VERIFIER); |
||||
} else { |
||||
conn = (HttpURLConnection) urlConn; |
||||
} |
||||
return conn; |
||||
} |
||||
|
||||
/** |
||||
* 设置头部参数 |
||||
*/ |
||||
public static HttpURLConnection setConnectParam(HttpTaskOption delegate, HttpURLConnection conn) { |
||||
if (delegate.getRequestEnum() == RequestEnum.POST) { |
||||
conn.setDoInput(true); |
||||
conn.setDoOutput(true); |
||||
conn.setUseCaches(false); |
||||
} |
||||
Set<String> keys = null; |
||||
if (delegate.getHeaders() != null && delegate.getHeaders().size() > 0) { |
||||
keys = delegate.getHeaders().keySet(); |
||||
for (String key : keys) { |
||||
conn.setRequestProperty(key, delegate.getHeaders().get(key)); |
||||
} |
||||
} |
||||
if (conn.getRequestProperty("Accept-Language") == null) { |
||||
conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7"); |
||||
} |
||||
if (conn.getRequestProperty("Accept-Encoding") == null) { |
||||
conn.setRequestProperty("Accept-Encoding", "identity"); |
||||
} |
||||
if (conn.getRequestProperty("Accept-Charset") == null) { |
||||
conn.setRequestProperty("Accept-Charset", "UTF-8"); |
||||
} |
||||
if (conn.getRequestProperty("Connection") == null) { |
||||
conn.setRequestProperty("Connection", "Keep-Alive"); |
||||
} |
||||
if (conn.getRequestProperty("Charset") == null) { |
||||
conn.setRequestProperty("Charset", "UTF-8"); |
||||
} |
||||
if (conn.getRequestProperty("User-Agent") == null) { |
||||
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 (conn.getRequestProperty("Accept") == null) { |
||||
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("application/signed-exchange, ") |
||||
.append("text/plain, ") |
||||
.append("text/html, ") |
||||
.append("*/*"); |
||||
conn.setRequestProperty("Accept", accept.toString()); |
||||
} |
||||
//302获取重定向地址
|
||||
conn.setInstanceFollowRedirects(false); |
||||
|
||||
CookieManager manager = delegate.getCookieManager(); |
||||
if (manager != null) { |
||||
CookieStore store = manager.getCookieStore(); |
||||
if (store != null && store.getCookies().size() > 0) { |
||||
conn.setRequestProperty("Cookie", |
||||
TextUtils.join(";", store.getCookies())); |
||||
} |
||||
} |
||||
|
||||
return conn; |
||||
} |
||||
} |
@ -1,111 +0,0 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import com.arialyy.aria.core.TaskRecord; |
||||
import com.arialyy.aria.core.ThreadRecord; |
||||
import com.arialyy.aria.core.common.RecordHandler; |
||||
import com.arialyy.aria.core.common.RecordHelper; |
||||
import com.arialyy.aria.core.config.Configuration; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import com.arialyy.aria.core.loader.IRecordHandler; |
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; |
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper; |
||||
import com.arialyy.aria.util.RecordUtil; |
||||
import java.util.ArrayList; |
||||
|
||||
/** |
||||
* @author lyy |
||||
* Date: 2019-09-23 |
||||
*/ |
||||
public final class HttpRecordHandler extends RecordHandler { |
||||
public HttpRecordHandler(AbsTaskWrapper wrapper) { |
||||
super(wrapper); |
||||
} |
||||
|
||||
@Override public void handlerTaskRecord(TaskRecord record) { |
||||
RecordHelper helper = new RecordHelper(getWrapper(), record); |
||||
if (getWrapper().isSupportBP() && record.threadNum > 1) { |
||||
if (record.isBlock) { |
||||
helper.handleBlockRecord(); |
||||
} else { |
||||
helper.handleMultiRecord(); |
||||
} |
||||
} else if (!getWrapper().isSupportBP()) { |
||||
helper.handleNoSupportBPRecord(); |
||||
} else { |
||||
helper.handleSingleThreadRecord(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public ThreadRecord createThreadRecord(TaskRecord record, int threadId, long startL, long endL) { |
||||
ThreadRecord tr; |
||||
tr = new ThreadRecord(); |
||||
tr.taskKey = record.filePath; |
||||
tr.threadId = threadId; |
||||
tr.startLocation = startL; |
||||
tr.isComplete = false; |
||||
|
||||
tr.threadType = record.taskType; |
||||
//最后一个线程的结束位置即为文件的总长度
|
||||
if (threadId == (record.threadNum - 1)) { |
||||
endL = getFileSize(); |
||||
} |
||||
tr.endLocation = endL; |
||||
tr.blockLen = RecordUtil.getBlockLen(getFileSize(), threadId, record.threadNum); |
||||
return tr; |
||||
} |
||||
|
||||
@Override public TaskRecord createTaskRecord(int threadNum) { |
||||
TaskRecord record = new TaskRecord(); |
||||
record.fileName = getEntity().getFileName(); |
||||
record.filePath = getEntity().getFilePath(); |
||||
record.threadRecords = new ArrayList<>(); |
||||
record.threadNum = threadNum; |
||||
|
||||
int requestType = getWrapper().getRequestType(); |
||||
if (requestType == ITaskWrapper.D_HTTP || requestType == ITaskWrapper.DG_HTTP) { |
||||
record.isBlock = Configuration.getInstance().downloadCfg.isUseBlock(); |
||||
} else { |
||||
record.isBlock = false; |
||||
} |
||||
record.taskType = requestType; |
||||
record.isGroupRecord = getEntity().isGroupChild(); |
||||
if (record.isGroupRecord) { |
||||
if (getEntity() instanceof DownloadEntity) { |
||||
record.dGroupHash = ((DownloadEntity) getEntity()).getGroupHash(); |
||||
} |
||||
} |
||||
|
||||
return record; |
||||
} |
||||
|
||||
@Override public int initTaskThreadNum() { |
||||
int requestTpe = getWrapper().getRequestType(); |
||||
if (requestTpe == ITaskWrapper.U_HTTP |
||||
|| (requestTpe == ITaskWrapper.D_HTTP && (!getWrapper().isSupportBP()) |
||||
|| ((HttpTaskOption) getWrapper().getTaskOption()).isChunked())) { |
||||
return 1; |
||||
} |
||||
int threadNum = Configuration.getInstance().downloadCfg.getThreadNum(); |
||||
return getFileSize() <= IRecordHandler.SUB_LEN |
||||
|| getEntity().isGroupChild() |
||||
|| threadNum == 1 |
||||
? 1 |
||||
: threadNum; |
||||
} |
||||
} |
@ -1,191 +0,0 @@ |
||||
/* |
||||
* 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.http; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.common.RequestEnum; |
||||
import com.arialyy.aria.core.inf.ITaskOption; |
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter; |
||||
import com.arialyy.aria.core.processor.IHttpFileNameAdapter; |
||||
|
||||
import java.lang.ref.SoftReference; |
||||
import java.net.CookieManager; |
||||
import java.net.Proxy; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Http任务设置的信息,如:cookie、请求参数 |
||||
*/ |
||||
public final class HttpTaskOption implements ITaskOption { |
||||
|
||||
private CookieManager cookieManager; |
||||
|
||||
/** |
||||
* 请求参数 |
||||
*/ |
||||
private Map<String, String> params; |
||||
|
||||
/** |
||||
* http 请求头 |
||||
*/ |
||||
private Map<String, String> headers = new HashMap<>(); |
||||
|
||||
/** |
||||
* 字符编码,默认为"utf-8" |
||||
*/ |
||||
private String charSet = "utf-8"; |
||||
|
||||
/** |
||||
* 网络请求类型 |
||||
*/ |
||||
private RequestEnum requestEnum = RequestEnum.GET; |
||||
|
||||
/** |
||||
* 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment; filename="filename.jpg"} {@code true} |
||||
* 使用 |
||||
*/ |
||||
private boolean useServerFileName = false; |
||||
|
||||
/** |
||||
* 重定向链接 |
||||
*/ |
||||
private String redirectUrl = ""; |
||||
|
||||
/** |
||||
* 是否是chunk模式 |
||||
*/ |
||||
private boolean isChunked = false; |
||||
/** |
||||
* 文件上传需要的key |
||||
*/ |
||||
private String attachment; |
||||
|
||||
private Proxy proxy; |
||||
/** |
||||
* 文件上传表单 |
||||
*/ |
||||
private Map<String, String> formFields = new HashMap<>(); |
||||
|
||||
private SoftReference<IHttpFileLenAdapter> fileLenAdapter; |
||||
|
||||
private SoftReference<IHttpFileNameAdapter> fileNameAdapter; |
||||
|
||||
public IHttpFileLenAdapter getFileLenAdapter() { |
||||
return fileLenAdapter == null ? null : fileLenAdapter.get(); |
||||
} |
||||
public IHttpFileNameAdapter getFileNameAdapter() { |
||||
return fileNameAdapter == null ? null : fileNameAdapter.get(); |
||||
} |
||||
/** |
||||
* 如果是匿名内部类,完成后需要将adapter设置为空,否则会出现内存泄漏 |
||||
*/ |
||||
public void setFileLenAdapter(IHttpFileLenAdapter fileLenAdapter) { |
||||
this.fileLenAdapter = new SoftReference<>(fileLenAdapter); |
||||
} |
||||
public void setFileNameAdapter(IHttpFileNameAdapter fileNameAdapter) { |
||||
this.fileNameAdapter = new SoftReference<>(fileNameAdapter); |
||||
} |
||||
public Map<String, String> getFormFields() { |
||||
return formFields; |
||||
} |
||||
|
||||
public void setFormFields(Map<String, String> formFields) { |
||||
this.formFields = formFields; |
||||
} |
||||
|
||||
public String getAttachment() { |
||||
return TextUtils.isEmpty(attachment) ? "file" : attachment; |
||||
} |
||||
|
||||
public void setAttachment(String attachment) { |
||||
this.attachment = attachment; |
||||
} |
||||
|
||||
public boolean isChunked() { |
||||
return isChunked; |
||||
} |
||||
|
||||
public void setChunked(boolean chunked) { |
||||
isChunked = chunked; |
||||
} |
||||
|
||||
public CookieManager getCookieManager() { |
||||
return cookieManager; |
||||
} |
||||
|
||||
public void setCookieManager(CookieManager cookieManager) { |
||||
this.cookieManager = cookieManager; |
||||
} |
||||
|
||||
public Proxy getProxy() { |
||||
return proxy; |
||||
} |
||||
|
||||
public void setProxy(Proxy proxy) { |
||||
this.proxy = proxy; |
||||
} |
||||
|
||||
public Map<String, String> getHeaders() { |
||||
return headers; |
||||
} |
||||
|
||||
public void setHeaders(Map<String, String> headers) { |
||||
this.headers = headers; |
||||
} |
||||
|
||||
public String getCharSet() { |
||||
return TextUtils.isEmpty(charSet) ? "utf-8" : charSet; |
||||
} |
||||
|
||||
public void setCharSet(String charSet) { |
||||
this.charSet = charSet; |
||||
} |
||||
|
||||
public RequestEnum getRequestEnum() { |
||||
return requestEnum; |
||||
} |
||||
|
||||
public void setRequestEnum(RequestEnum requestEnum) { |
||||
this.requestEnum = requestEnum; |
||||
} |
||||
|
||||
public boolean isUseServerFileName() { |
||||
return useServerFileName; |
||||
} |
||||
|
||||
public void setUseServerFileName(boolean useServerFileName) { |
||||
this.useServerFileName = useServerFileName; |
||||
} |
||||
|
||||
public String getRedirectUrl() { |
||||
return redirectUrl; |
||||
} |
||||
|
||||
public void setRedirectUrl(String redirectUrl) { |
||||
this.redirectUrl = redirectUrl; |
||||
} |
||||
|
||||
public Map<String, String> getParams() { |
||||
return params; |
||||
} |
||||
|
||||
public void setParams(Map<String, String> params) { |
||||
this.params = params; |
||||
} |
||||
|
||||
} |
@ -1,31 +1,41 @@ |
||||
/* |
||||
* 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.http.upload |
||||
|
||||
import com.arialyy.aria.core.task.ITaskInterceptor |
||||
import com.arialyy.aria.core.task.TaskChain |
||||
import com.arialyy.aria.core.task.TaskResp |
||||
|
||||
/** |
||||
* @Author laoyuyu |
||||
* @Description |
||||
* @Date 9:47 PM 2023/2/21 |
||||
**/ |
||||
class HttpUBlockInterceptor: ITaskInterceptor { |
||||
override suspend fun interceptor(chain: TaskChain): TaskResp { |
||||
|
||||
} |
||||
} |
||||
///* |
||||
// * 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.http.upload |
||||
// |
||||
//import com.arialyy.aria.core.inf.IBlockManager |
||||
//import com.arialyy.aria.core.task.ITask |
||||
//import com.arialyy.aria.core.task.ITaskInterceptor |
||||
//import com.arialyy.aria.core.task.TaskChain |
||||
//import com.arialyy.aria.core.task.TaskResp |
||||
//import com.arialyy.aria.http.HttpTaskOption |
||||
//import com.arialyy.aria.orm.entity.TaskRecord |
||||
// |
||||
///** |
||||
// * @Author laoyuyu |
||||
// * @Description |
||||
// * @Date 9:47 PM 2023/2/21 |
||||
// **/ |
||||
//class HttpUBlockInterceptor: ITaskInterceptor { |
||||
// |
||||
// private lateinit var task: ITask |
||||
// private lateinit var option: HttpTaskOption |
||||
// private lateinit var blockManager: IBlockManager |
||||
// private lateinit var taskRecord: TaskRecord |
||||
// |
||||
// override suspend fun interceptor(chain: TaskChain): TaskResp { |
||||
// |
||||
// } |
||||
//} |
@ -1,94 +0,0 @@ |
||||
/* |
||||
* 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.http.upload; |
||||
|
||||
import android.os.Handler; |
||||
import android.os.Looper; |
||||
import com.arialyy.aria.core.inf.IBlockManager; |
||||
import com.arialyy.aria.core.listener.IEventListener; |
||||
import com.arialyy.aria.core.loader.AbsNormalLoader; |
||||
import com.arialyy.aria.core.loader.IInfoTask; |
||||
import com.arialyy.aria.core.loader.IRecordHandler; |
||||
import com.arialyy.aria.core.loader.IThreadTaskBuilder; |
||||
import com.arialyy.aria.core.manager.ThreadTaskManager; |
||||
import com.arialyy.aria.core.task.IThreadTask; |
||||
import com.arialyy.aria.core.upload.UTaskWrapper; |
||||
import com.arialyy.aria.exception.AriaHTTPException; |
||||
import com.arialyy.aria.util.ALog; |
||||
import java.util.List; |
||||
|
||||
final class HttpULoader1 extends AbsNormalLoader<UTaskWrapper> { |
||||
HttpULoader1(UTaskWrapper wrapper, IEventListener listener) { |
||||
super(wrapper, listener); |
||||
} |
||||
|
||||
@Override public void addComponent(IRecordHandler recordHandler) { |
||||
mRecordHandler = recordHandler; |
||||
} |
||||
|
||||
/** |
||||
* @deprecated http 上传任务不需要设置这个 |
||||
*/ |
||||
@Deprecated |
||||
@Override public void addComponent(IInfoTask infoTask) { |
||||
|
||||
} |
||||
|
||||
@Override public void addComponent(IBlockManager threadState) { |
||||
mStateManager = threadState; |
||||
} |
||||
|
||||
@Override public void addComponent(IThreadTaskBuilder builder) { |
||||
mTTBuilder = builder; |
||||
} |
||||
|
||||
@Override protected void handleTask(Looper looper) { |
||||
mRecord = mRecordHandler.getRecord(getFileSize()); |
||||
mStateManager.setLooper(mRecord, looper); |
||||
List<IThreadTask> tt = mTTBuilder.buildThreadTask(mRecord, |
||||
new Handler(looper, mStateManager.getHandlerCallback())); |
||||
if (tt == null || tt.isEmpty()) { |
||||
ALog.e(TAG, "创建线程任务失败"); |
||||
getListener().onFail(false, new AriaHTTPException("创建线程任务失败")); |
||||
return; |
||||
} |
||||
|
||||
getListener().onStart(0); |
||||
ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), tt.get(0)); |
||||
|
||||
startTimer(); |
||||
} |
||||
|
||||
@Override public long getFileSize() { |
||||
return mTaskWrapper.getEntity().getFileSize(); |
||||
} |
||||
|
||||
@Override protected void checkComponent() { |
||||
if (mRecordHandler == null) { |
||||
throw new NullPointerException("任务记录组件为空"); |
||||
} |
||||
if (mStateManager == null) { |
||||
throw new NullPointerException("任务状态管理组件为空"); |
||||
} |
||||
if (mTTBuilder == null) { |
||||
throw new NullPointerException("线程任务组件为空"); |
||||
} |
||||
} |
||||
|
||||
@Override public long getCurrentProgress() { |
||||
return mStateManager.getCurrentProgress(); |
||||
} |
||||
} |
@ -1,62 +0,0 @@ |
||||
/* |
||||
* 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.http.upload; |
||||
|
||||
import com.arialyy.aria.core.TaskRecord; |
||||
import com.arialyy.aria.core.common.SubThreadConfig; |
||||
import com.arialyy.aria.core.loader.AbsNormalLoader; |
||||
import com.arialyy.aria.core.loader.AbsNormalLoaderUtil; |
||||
import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter; |
||||
import com.arialyy.aria.core.loader.LoaderStructure; |
||||
import com.arialyy.aria.core.loader.NormalTTBuilder; |
||||
import com.arialyy.aria.core.loader.UploadThreadStateManager; |
||||
import com.arialyy.aria.core.task.IThreadTaskAdapter; |
||||
import com.arialyy.aria.core.upload.UTaskWrapper; |
||||
import com.arialyy.aria.http.HttpRecordHandler; |
||||
import com.arialyy.aria.http.HttpTaskOption; |
||||
|
||||
/** |
||||
* @author lyy |
||||
* Date: 2019-09-19 |
||||
*/ |
||||
public final class HttpULoaderUtil extends AbsNormalLoaderUtil { |
||||
|
||||
@Override public AbsNormalLoader getLoader() { |
||||
if (mLoader == null) { |
||||
getTaskWrapper().generateTaskOption(HttpTaskOption.class); |
||||
mLoader = new HttpULoader1((UTaskWrapper) getTaskWrapper(), getListener()); |
||||
} |
||||
return mLoader; |
||||
} |
||||
|
||||
@Override public LoaderStructure BuildLoaderStructure() { |
||||
LoaderStructure structure = new LoaderStructure(); |
||||
structure.addComponent(new HttpRecordHandler(getTaskWrapper())) |
||||
// .addComponent(new NormalThreadStateManager(getListener()))
|
||||
.addComponent(new UploadThreadStateManager(getListener())) |
||||
.addComponent(new NormalTTBuilder(getTaskWrapper(), new AbsNormalTTBuilderAdapter() { |
||||
@Override public IThreadTaskAdapter getAdapter(SubThreadConfig config) { |
||||
return new HttpUThreadTaskAdapter(config); |
||||
} |
||||
|
||||
@Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) { |
||||
return true; |
||||
} |
||||
})); |
||||
structure.accept(getLoader()); |
||||
return structure; |
||||
} |
||||
} |
@ -1,235 +1,235 @@ |
||||
/* |
||||
* 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.http.upload; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.common.SubThreadConfig; |
||||
import com.arialyy.aria.core.upload.UploadEntity; |
||||
import com.arialyy.aria.exception.AriaHTTPException; |
||||
import com.arialyy.aria.http.BaseHttpThreadTaskAdapter; |
||||
import com.arialyy.aria.http.ConnectionHelp; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import java.io.BufferedReader; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStreamReader; |
||||
import java.io.OutputStream; |
||||
import java.io.OutputStreamWriter; |
||||
import java.io.PrintWriter; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.net.URLConnection; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* Created by Aria.Lao on 2017/7/28. 不支持断点的HTTP上传任务 |
||||
*/ |
||||
final class HttpUThreadTaskAdapter extends BaseHttpThreadTaskAdapter { |
||||
|
||||
private final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
|
||||
private final String PREFIX = "--", LINE_END = "\r\n"; |
||||
private HttpURLConnection mHttpConn; |
||||
private OutputStream mOutputStream; |
||||
|
||||
HttpUThreadTaskAdapter(SubThreadConfig config) { |
||||
super(config); |
||||
} |
||||
|
||||
@Override protected void handlerThreadTask() { |
||||
File uploadFile = new File(getEntity().getFilePath()); |
||||
if (!uploadFile.exists()) { |
||||
fail(new AriaHTTPException( |
||||
String.format("上传失败,文件不存在;filePath: %s, url: %s", getEntity().getFilePath(), |
||||
getEntity().getUrl()))); |
||||
return; |
||||
} |
||||
URL url; |
||||
try { |
||||
url = new URL(CommonUtil.convertUrl(getThreadConfig().url)); |
||||
|
||||
mHttpConn = (HttpURLConnection) url.openConnection(); |
||||
mHttpConn.setRequestMethod(mTaskOption.getRequestEnum().name); |
||||
mHttpConn.setUseCaches(false); |
||||
mHttpConn.setDoOutput(true); |
||||
mHttpConn.setDoInput(true); |
||||
mHttpConn.setRequestProperty("Connection", "Keep-Alive"); |
||||
mHttpConn.setRequestProperty("Content-Type", |
||||
getContentType() + "; boundary=" + BOUNDARY); |
||||
mHttpConn.setRequestProperty("User-Agent", getUserAgent()); |
||||
mHttpConn.setConnectTimeout(getTaskConfig().getConnectTimeOut()); |
||||
mHttpConn.setReadTimeout(getTaskConfig().getIOTimeOut()); |
||||
//内部缓冲区---分段上传防止oom
|
||||
mHttpConn.setChunkedStreamingMode(getTaskConfig().getBuffSize()); |
||||
|
||||
//添加Http请求头部
|
||||
Set<String> keys = mTaskOption.getHeaders().keySet(); |
||||
for (String key : keys) { |
||||
mHttpConn.setRequestProperty(key, mTaskOption.getHeaders().get(key)); |
||||
} |
||||
mOutputStream = mHttpConn.getOutputStream(); |
||||
PrintWriter writer = |
||||
new PrintWriter(new OutputStreamWriter(mOutputStream, mTaskOption.getCharSet()), true); |
||||
// 添加参数
|
||||
Map<String, String> params = mTaskOption.getParams(); |
||||
if (params != null && !params.isEmpty()) { |
||||
for (String key : params.keySet()) { |
||||
addFormField(writer, key, params.get(key)); |
||||
} |
||||
} |
||||
|
||||
//添加文件上传表单字段
|
||||
keys = mTaskOption.getFormFields().keySet(); |
||||
for (String key : keys) { |
||||
addFormField(writer, key, mTaskOption.getFormFields().get(key)); |
||||
} |
||||
|
||||
uploadFile(writer, mTaskOption.getAttachment(), uploadFile); |
||||
finish(writer); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
fail(new AriaHTTPException( |
||||
String.format("上传失败,filePath: %s, url: %s", getEntity().getFilePath(), |
||||
getEntity().getUrl()), e)); |
||||
} |
||||
} |
||||
|
||||
private void fail(AriaHTTPException e1) { |
||||
try { |
||||
fail(e1, false); |
||||
if (mOutputStream != null) { |
||||
mOutputStream.close(); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
private String getContentType() { |
||||
///*
|
||||
// * 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.http.upload;
|
||||
//
|
||||
//import android.text.TextUtils;
|
||||
//import com.arialyy.aria.core.common.SubThreadConfig;
|
||||
//import com.arialyy.aria.core.upload.UploadEntity;
|
||||
//import com.arialyy.aria.exception.AriaHTTPException;
|
||||
//import com.arialyy.aria.http.BaseHttpThreadTaskAdapter;
|
||||
//import com.arialyy.aria.http.ConnectionHelp;
|
||||
//import com.arialyy.aria.util.ALog;
|
||||
//import com.arialyy.aria.util.CommonUtil;
|
||||
//import java.io.BufferedReader;
|
||||
//import java.io.File;
|
||||
//import java.io.FileInputStream;
|
||||
//import java.io.FileOutputStream;
|
||||
//import java.io.IOException;
|
||||
//import java.io.InputStreamReader;
|
||||
//import java.io.OutputStream;
|
||||
//import java.io.OutputStreamWriter;
|
||||
//import java.io.PrintWriter;
|
||||
//import java.net.HttpURLConnection;
|
||||
//import java.net.URL;
|
||||
//import java.net.URLConnection;
|
||||
//import java.util.Map;
|
||||
//import java.util.Set;
|
||||
//import java.util.UUID;
|
||||
//
|
||||
///**
|
||||
// * Created by Aria.Lao on 2017/7/28. 不支持断点的HTTP上传任务
|
||||
// */
|
||||
//final class HttpUThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
|
||||
//
|
||||
// private final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
|
||||
// private final String PREFIX = "--", LINE_END = "\r\n";
|
||||
// private HttpURLConnection mHttpConn;
|
||||
// private OutputStream mOutputStream;
|
||||
//
|
||||
// HttpUThreadTaskAdapter(SubThreadConfig config) {
|
||||
// super(config);
|
||||
// }
|
||||
//
|
||||
// @Override protected void handlerThreadTask() {
|
||||
// File uploadFile = new File(getEntity().getFilePath());
|
||||
// if (!uploadFile.exists()) {
|
||||
// fail(new AriaHTTPException(
|
||||
// String.format("上传失败,文件不存在;filePath: %s, url: %s", getEntity().getFilePath(),
|
||||
// getEntity().getUrl())));
|
||||
// return;
|
||||
// }
|
||||
// URL url;
|
||||
// try {
|
||||
// url = new URL(CommonUtil.convertUrl(getThreadConfig().url));
|
||||
//
|
||||
// mHttpConn = (HttpURLConnection) url.openConnection();
|
||||
// mHttpConn.setRequestMethod(mTaskOption.getRequestEnum().name);
|
||||
// mHttpConn.setUseCaches(false);
|
||||
// mHttpConn.setDoOutput(true);
|
||||
// mHttpConn.setDoInput(true);
|
||||
// mHttpConn.setRequestProperty("Connection", "Keep-Alive");
|
||||
// mHttpConn.setRequestProperty("Content-Type",
|
||||
// getContentType() + "; boundary=" + BOUNDARY);
|
||||
// mHttpConn.setRequestProperty("User-Agent", getUserAgent());
|
||||
// mHttpConn.setConnectTimeout(getTaskConfig().getConnectTimeOut());
|
||||
// mHttpConn.setReadTimeout(getTaskConfig().getIOTimeOut());
|
||||
// //内部缓冲区---分段上传防止oom
|
||||
// mHttpConn.setChunkedStreamingMode(getTaskConfig().getBuffSize());
|
||||
//
|
||||
// //添加Http请求头部
|
||||
// Set<String> keys = mTaskOption.getHeaders().keySet();
|
||||
// for (String key : keys) {
|
||||
// mHttpConn.setRequestProperty(key, mTaskOption.getHeaders().get(key));
|
||||
// }
|
||||
// mOutputStream = mHttpConn.getOutputStream();
|
||||
// PrintWriter writer =
|
||||
// new PrintWriter(new OutputStreamWriter(mOutputStream, mTaskOption.getCharSet()), true);
|
||||
// // 添加参数
|
||||
// Map<String, String> params = mTaskOption.getParams();
|
||||
// if (params != null && !params.isEmpty()) {
|
||||
// for (String key : params.keySet()) {
|
||||
// addFormField(writer, key, params.get(key));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //添加文件上传表单字段
|
||||
// keys = mTaskOption.getFormFields().keySet();
|
||||
// for (String key : keys) {
|
||||
// addFormField(writer, key, mTaskOption.getFormFields().get(key));
|
||||
// }
|
||||
//
|
||||
// uploadFile(writer, mTaskOption.getAttachment(), uploadFile);
|
||||
// finish(writer);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// fail(new AriaHTTPException(
|
||||
// String.format("上传失败,filePath: %s, url: %s", getEntity().getFilePath(),
|
||||
// getEntity().getUrl()), e));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void fail(AriaHTTPException e1) {
|
||||
// try {
|
||||
// fail(e1, false);
|
||||
// if (mOutputStream != null) {
|
||||
// mOutputStream.close();
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private String getContentType() {
|
||||
// //return (mTaskOption.getHeaders() == null || TextUtils.isEmpty(
|
||||
// // mTaskOption.getHeaders().get("Content-Type"))) ? "multipart/form-data"
|
||||
// // : mTaskOption.getHeaders().get("Content-Type");
|
||||
// return "multipart/form-data";
|
||||
// }
|
||||
//
|
||||
// private String getUserAgent() {
|
||||
// return (mTaskOption.getHeaders() == null || TextUtils.isEmpty(
|
||||
// mTaskOption.getHeaders().get("Content-Type"))) ? "multipart/form-data"
|
||||
// : mTaskOption.getHeaders().get("Content-Type");
|
||||
return "multipart/form-data"; |
||||
} |
||||
|
||||
private String getUserAgent() { |
||||
return (mTaskOption.getHeaders() == null || TextUtils.isEmpty( |
||||
mTaskOption.getHeaders().get("User-Agent"))) |
||||
? "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)" |
||||
: mTaskOption.getHeaders().get("User-Agent"); |
||||
} |
||||
|
||||
/** |
||||
* 添加文件上传表单字段 |
||||
*/ |
||||
private void addFormField(PrintWriter writer, String name, String value) { |
||||
writer.append(PREFIX).append(BOUNDARY).append(LINE_END); |
||||
writer.append("Content-Disposition: form-data; name=\"") |
||||
.append(name) |
||||
.append("\"") |
||||
.append(LINE_END); |
||||
writer.append("Content-Type: text/plain; charset=") |
||||
.append(mTaskOption.getCharSet()) |
||||
.append(LINE_END); |
||||
writer.append(LINE_END); |
||||
writer.append(value).append(LINE_END); |
||||
writer.flush(); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件 |
||||
* |
||||
* @param attachment 文件上传attachment |
||||
* @throws IOException |
||||
*/ |
||||
private void uploadFile(PrintWriter writer, String attachment, File uploadFile) |
||||
throws IOException { |
||||
writer.append(PREFIX).append(BOUNDARY).append(LINE_END); |
||||
writer.append("Content-Disposition: form-data; name=\"") |
||||
.append(attachment) |
||||
.append("\"; filename=\"") |
||||
.append(getEntity().getFileName()) |
||||
.append("\"") |
||||
.append(LINE_END); |
||||
writer.append("Content-Type: ") |
||||
.append(URLConnection.guessContentTypeFromName(getEntity().getFileName())) |
||||
.append(LINE_END); |
||||
writer.append("Content-Transfer-Encoding: binary").append(LINE_END); |
||||
writer.append(LINE_END); |
||||
writer.flush(); |
||||
|
||||
FileInputStream inputStream = new FileInputStream(uploadFile); |
||||
byte[] buffer = new byte[4096]; |
||||
int bytesLen; |
||||
while ((bytesLen = inputStream.read(buffer)) != -1) { |
||||
mOutputStream.write(buffer, 0, bytesLen); |
||||
progress(bytesLen); |
||||
if (getThreadTask().isBreak()) { |
||||
break; |
||||
} |
||||
if (mSpeedBandUtil != null) { |
||||
mSpeedBandUtil.limitNextBytes(bytesLen); |
||||
} |
||||
} |
||||
|
||||
mOutputStream.flush(); |
||||
inputStream.close(); |
||||
writer.append(LINE_END).flush(); |
||||
// 保证上传的文件和本地的一致,https://www.cnblogs.com/tugenhua0707/p/8975121.html
|
||||
writer.append(PREFIX).append(BOUNDARY).append(PREFIX).append(LINE_END).flush(); |
||||
} |
||||
|
||||
/** |
||||
* 任务结束操作 |
||||
* |
||||
* @throws IOException |
||||
*/ |
||||
private String finish(PrintWriter writer) throws IOException { |
||||
StringBuilder response = new StringBuilder(); |
||||
int status = mHttpConn.getResponseCode(); |
||||
|
||||
if (status == HttpURLConnection.HTTP_OK) { |
||||
BufferedReader reader = |
||||
new BufferedReader(new InputStreamReader(ConnectionHelp.convertInputStream(mHttpConn))); |
||||
String line; |
||||
while (getThreadTask().isLive() && (line = reader.readLine()) != null) { |
||||
response.append(line); |
||||
} |
||||
reader.close(); |
||||
mHttpConn.disconnect(); |
||||
getEntity().setResponseStr(response.toString()); |
||||
complete(); |
||||
} else { |
||||
String msg = "response msg: " + mHttpConn.getResponseMessage() + ",code: " + status; |
||||
ALog.e(TAG, msg); |
||||
getEntity().setResponseStr(response.toString()); |
||||
fail(new AriaHTTPException(msg), false); |
||||
response.append(status); |
||||
} |
||||
writer.flush(); |
||||
writer.close(); |
||||
mOutputStream.close(); |
||||
return response.toString(); |
||||
} |
||||
|
||||
@Override protected UploadEntity getEntity() { |
||||
return (UploadEntity) super.getEntity(); |
||||
} |
||||
} |
||||
// mTaskOption.getHeaders().get("User-Agent")))
|
||||
// ? "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"
|
||||
// : mTaskOption.getHeaders().get("User-Agent");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 添加文件上传表单字段
|
||||
// */
|
||||
// private void addFormField(PrintWriter writer, String name, String value) {
|
||||
// writer.append(PREFIX).append(BOUNDARY).append(LINE_END);
|
||||
// writer.append("Content-Disposition: form-data; name=\"")
|
||||
// .append(name)
|
||||
// .append("\"")
|
||||
// .append(LINE_END);
|
||||
// writer.append("Content-Type: text/plain; charset=")
|
||||
// .append(mTaskOption.getCharSet())
|
||||
// .append(LINE_END);
|
||||
// writer.append(LINE_END);
|
||||
// writer.append(value).append(LINE_END);
|
||||
// writer.flush();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 上传文件
|
||||
// *
|
||||
// * @param attachment 文件上传attachment
|
||||
// * @throws IOException
|
||||
// */
|
||||
// private void uploadFile(PrintWriter writer, String attachment, File uploadFile)
|
||||
// throws IOException {
|
||||
// writer.append(PREFIX).append(BOUNDARY).append(LINE_END);
|
||||
// writer.append("Content-Disposition: form-data; name=\"")
|
||||
// .append(attachment)
|
||||
// .append("\"; filename=\"")
|
||||
// .append(getEntity().getFileName())
|
||||
// .append("\"")
|
||||
// .append(LINE_END);
|
||||
// writer.append("Content-Type: ")
|
||||
// .append(URLConnection.guessContentTypeFromName(getEntity().getFileName()))
|
||||
// .append(LINE_END);
|
||||
// writer.append("Content-Transfer-Encoding: binary").append(LINE_END);
|
||||
// writer.append(LINE_END);
|
||||
// writer.flush();
|
||||
//
|
||||
// FileInputStream inputStream = new FileInputStream(uploadFile);
|
||||
// byte[] buffer = new byte[4096];
|
||||
// int bytesLen;
|
||||
// while ((bytesLen = inputStream.read(buffer)) != -1) {
|
||||
// mOutputStream.write(buffer, 0, bytesLen);
|
||||
// progress(bytesLen);
|
||||
// if (getThreadTask().isBreak()) {
|
||||
// break;
|
||||
// }
|
||||
// if (mSpeedBandUtil != null) {
|
||||
// mSpeedBandUtil.limitNextBytes(bytesLen);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// mOutputStream.flush();
|
||||
// inputStream.close();
|
||||
// writer.append(LINE_END).flush();
|
||||
// // 保证上传的文件和本地的一致,https://www.cnblogs.com/tugenhua0707/p/8975121.html
|
||||
// writer.append(PREFIX).append(BOUNDARY).append(PREFIX).append(LINE_END).flush();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 任务结束操作
|
||||
// *
|
||||
// * @throws IOException
|
||||
// */
|
||||
// private String finish(PrintWriter writer) throws IOException {
|
||||
// StringBuilder response = new StringBuilder();
|
||||
// int status = mHttpConn.getResponseCode();
|
||||
//
|
||||
// if (status == HttpURLConnection.HTTP_OK) {
|
||||
// BufferedReader reader =
|
||||
// new BufferedReader(new InputStreamReader(ConnectionHelp.convertInputStream(mHttpConn)));
|
||||
// String line;
|
||||
// while (getThreadTask().isLive() && (line = reader.readLine()) != null) {
|
||||
// response.append(line);
|
||||
// }
|
||||
// reader.close();
|
||||
// mHttpConn.disconnect();
|
||||
// getEntity().setResponseStr(response.toString());
|
||||
// complete();
|
||||
// } else {
|
||||
// String msg = "response msg: " + mHttpConn.getResponseMessage() + ",code: " + status;
|
||||
// ALog.e(TAG, msg);
|
||||
// getEntity().setResponseStr(response.toString());
|
||||
// fail(new AriaHTTPException(msg), false);
|
||||
// response.append(status);
|
||||
// }
|
||||
// writer.flush();
|
||||
// writer.close();
|
||||
// mOutputStream.close();
|
||||
// return response.toString();
|
||||
// }
|
||||
//
|
||||
// @Override protected UploadEntity getEntity() {
|
||||
// return (UploadEntity) super.getEntity();
|
||||
// }
|
||||
//}
|
||||
|
@ -1,275 +0,0 @@ |
||||
/* |
||||
* 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.loader; |
||||
|
||||
import android.os.Bundle; |
||||
import android.os.Handler; |
||||
import android.os.Looper; |
||||
import android.os.Message; |
||||
|
||||
import com.arialyy.aria.core.TaskRecord; |
||||
import com.arialyy.aria.core.inf.IBlockManager; |
||||
import com.arialyy.aria.core.listener.IEventListener; |
||||
import com.arialyy.aria.exception.AriaException; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import com.arialyy.aria.util.FileUtil; |
||||
|
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
||||
/** |
||||
* 线程任务管理器,用于处理多线程下载时任务的状态回调 |
||||
*/ |
||||
public class UploadThreadStateManager implements IBlockManager { |
||||
private final String TAG = CommonUtil.getClassName(this); |
||||
|
||||
/** |
||||
* 任务状态回调 |
||||
*/ |
||||
private IEventListener mListener; |
||||
private int mThreadNum; // 启动的线程总数
|
||||
private AtomicInteger mCancelNum = new AtomicInteger(0); // 已经取消的线程的数
|
||||
private AtomicInteger mStopNum = new AtomicInteger(0); // 已经停止的线程数
|
||||
private AtomicInteger mFailNum = new AtomicInteger(0); // 失败的线程数
|
||||
private AtomicInteger mCompleteNum = new AtomicInteger(0); // 完成的线程数
|
||||
private long mProgress; //当前总进度
|
||||
private TaskRecord mTaskRecord; // 任务记录
|
||||
private Looper mLooper; |
||||
|
||||
/** |
||||
* @param listener 任务事件 |
||||
*/ |
||||
public UploadThreadStateManager(IEventListener listener) { |
||||
mListener = listener; |
||||
} |
||||
|
||||
@Override public void setLooper(TaskRecord taskRecord, Looper looper) { |
||||
mTaskRecord = taskRecord; |
||||
mThreadNum = mTaskRecord.threadNum; |
||||
mLooper = looper; |
||||
} |
||||
|
||||
private void checkLooper() { |
||||
if (mTaskRecord == null) { |
||||
throw new NullPointerException("任务记录为空"); |
||||
} |
||||
if (mLooper == null) { |
||||
throw new NullPointerException("Looper为空"); |
||||
} |
||||
} |
||||
|
||||
private Handler.Callback callback = new Handler.Callback() { |
||||
@Override public boolean handleMessage(Message msg) { |
||||
checkLooper(); |
||||
switch (msg.what) { |
||||
case STATE_STOP: |
||||
mStopNum.getAndIncrement(); |
||||
if (isStop()) { |
||||
quitLooper(); |
||||
} |
||||
break; |
||||
case STATE_CANCEL: |
||||
mCancelNum.getAndIncrement(); |
||||
if (isCancel()) { |
||||
quitLooper(); |
||||
} |
||||
break; |
||||
case STATE_FAIL: |
||||
mFailNum.getAndIncrement(); |
||||
if (hasFailedBlock()) { |
||||
Bundle b = msg.getData(); |
||||
mListener.onFail(b.getBoolean(DATA_RETRY, false), |
||||
(AriaException) b.getSerializable(DATA_ERROR_INFO)); |
||||
quitLooper(); |
||||
} |
||||
break; |
||||
case STATE_COMPLETE: |
||||
mCompleteNum.getAndIncrement(); |
||||
if (isCompleted()) { |
||||
ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum); |
||||
//上传文件不需要合并文件
|
||||
mListener.onComplete(); |
||||
quitLooper(); |
||||
} |
||||
break; |
||||
case STATE_RUNNING: |
||||
Bundle b = msg.getData(); |
||||
if (b != null) { |
||||
long len = b.getLong(IBlockManager.DATA_ADD_LEN, 0); |
||||
mProgress += len; |
||||
} |
||||
|
||||
break; |
||||
case STATE_UPDATE_PROGRESS: |
||||
if (msg.obj == null) { |
||||
mProgress = updateBlockProgress(); |
||||
} else if (msg.obj instanceof Long) { |
||||
mProgress = (long) msg.obj; |
||||
} |
||||
break; |
||||
} |
||||
return false; |
||||
} |
||||
}; |
||||
|
||||
@Override public void updateCurrentProgress(long currentProgress) { |
||||
mProgress = currentProgress; |
||||
} |
||||
|
||||
/** |
||||
* 退出looper循环 |
||||
*/ |
||||
private void quitLooper() { |
||||
mLooper.quit(); |
||||
} |
||||
|
||||
/** |
||||
* 获取当前任务下载进度 |
||||
* |
||||
* @return 当前任务下载进度 |
||||
*/ |
||||
@Override |
||||
public long getCurrentProgress() { |
||||
return mProgress; |
||||
} |
||||
|
||||
@Override public Handler.Callback getHandlerCallback() { |
||||
return callback; |
||||
} |
||||
|
||||
/** |
||||
* 所有子线程是否都已经停止 |
||||
*/ |
||||
public boolean isStop() { |
||||
//ALog.d(TAG,
|
||||
// String.format("isStop; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
|
||||
// mCancelNum, mFailNum, mCompleteNum));
|
||||
return mStopNum.get() == mThreadNum || mStopNum.get() + mCompleteNum.get() == mThreadNum; |
||||
} |
||||
|
||||
/** |
||||
* 所有子线程是否都已经失败 |
||||
*/ |
||||
@Override |
||||
public boolean hasFailedBlock() { |
||||
//ALog.d(TAG,
|
||||
// String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
|
||||
// mCancelNum, mFailNum, mCompleteNum));
|
||||
return mCompleteNum.get() != mThreadNum |
||||
&& (mFailNum.get() == mThreadNum || mFailNum.get() + mCompleteNum.get() == mThreadNum); |
||||
} |
||||
|
||||
/** |
||||
* 所有子线程是否都已经完成 |
||||
*/ |
||||
@Override |
||||
public boolean isCompleted() { |
||||
//ALog.d(TAG,
|
||||
// String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
|
||||
// mStopNum,
|
||||
// mCancelNum, mFailNum, mCompleteNum));
|
||||
return mCompleteNum.get() == mThreadNum; |
||||
} |
||||
|
||||
/** |
||||
* 所有子线程是否都已经取消 |
||||
*/ |
||||
public boolean isCancel() { |
||||
//ALog.d(TAG, String.format("isCancel; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
|
||||
// mStopNum,
|
||||
// mCancelNum, mFailNum, mCompleteNum));
|
||||
return mCancelNum.get() == mThreadNum; |
||||
} |
||||
|
||||
/** |
||||
* 更新分块任务s的真实进度 |
||||
*/ |
||||
private long updateBlockProgress() { |
||||
long size = 0; |
||||
for (int i = 0, len = mTaskRecord.threadRecords.size(); i < len; i++) { |
||||
File temp = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i)); |
||||
if (temp.exists()) { |
||||
size += temp.length(); |
||||
} |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* 合并sftp的分块 |
||||
*/ |
||||
private boolean mergerSFtp() { |
||||
if (mTaskRecord.threadNum == 1) { |
||||
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0)); |
||||
return partFile.renameTo(new File(mTaskRecord.filePath)); |
||||
} |
||||
|
||||
List<String> partPath = new ArrayList<>(); |
||||
for (int i = 0, len = mTaskRecord.threadNum; i < len; i++) { |
||||
partPath.add(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i)); |
||||
} |
||||
FileUtil.mergeSFtpFile(mTaskRecord.filePath, partPath, mTaskRecord.fileLength); |
||||
for (String pp : partPath) { |
||||
FileUtil.deleteFile(pp); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* 合并文件 |
||||
* |
||||
* @return {@code true} 合并成功,{@code false}合并失败 |
||||
*/ |
||||
private boolean mergeFile() { |
||||
if (mTaskRecord.threadNum == 1) { |
||||
File targetFile = new File(mTaskRecord.filePath); |
||||
if (targetFile.exists() && targetFile.length() == mTaskRecord.fileLength){ |
||||
return true; |
||||
} |
||||
FileUtil.deleteFile(targetFile); |
||||
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0)); |
||||
return partFile.renameTo(targetFile); |
||||
} |
||||
|
||||
List<String> partPath = new ArrayList<>(); |
||||
for (int i = 0, len = mTaskRecord.threadNum; i < len; i++) { |
||||
partPath.add(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i)); |
||||
} |
||||
boolean isSuccess = FileUtil.mergeFile(mTaskRecord.filePath, partPath); |
||||
if (isSuccess) { |
||||
for (String pp : partPath) { |
||||
FileUtil.deleteFile(pp); |
||||
} |
||||
File targetFile = new File(mTaskRecord.filePath); |
||||
if (targetFile.exists() && targetFile.length() > mTaskRecord.fileLength) { |
||||
ALog.e(TAG, String.format("任务【%s】分块文件合并失败,下载长度超出文件真实长度,downloadLen: %s,fileSize: %s", |
||||
targetFile.getName(), targetFile.length(), mTaskRecord.fileLength)); |
||||
return false; |
||||
} |
||||
return true; |
||||
} else { |
||||
ALog.e(TAG, "合并失败"); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
@Override public void accept(ILoaderVisitor visitor) { |
||||
visitor.addComponent(this); |
||||
} |
||||
} |
Loading…
Reference in new issue