|
@@ -5,6 +5,56 @@ import { http } from '@kit.NetworkKit';
|
|
|
import { util } from '@kit.ArkTS';
|
|
import { util } from '@kit.ArkTS';
|
|
|
import { JSON } from '@kit.ArkTS';
|
|
import { JSON } from '@kit.ArkTS';
|
|
|
|
|
|
|
|
|
|
+function md5ConvertToWords(input: Uint8Array): number[] {
|
|
|
|
|
+ const words: number[] = [];
|
|
|
|
|
+ for (let i = 0; i < input.length; i++) {
|
|
|
|
|
+ const idx = (i >> 2);
|
|
|
|
|
+ words[idx] = words[idx] || 0;
|
|
|
|
|
+ words[idx] |= input[i] << ((i % 4) * 8);
|
|
|
|
|
+ }
|
|
|
|
|
+ return words;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5SafeAdd(x: number, y: number): number {
|
|
|
|
|
+ const lsw = (x & 0xffff) + (y & 0xffff);
|
|
|
|
|
+ const msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16);
|
|
|
|
|
+ return (msw << 16) | (lsw & 0xffff);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5RotateLeft(num: number, cnt: number): number {
|
|
|
|
|
+ return (num << cnt) | (num >>> (32 - cnt));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5Cmn(q: number, a: number, b: number, x: number, s: number, t: number): number {
|
|
|
|
|
+ return md5SafeAdd(md5RotateLeft(md5SafeAdd(md5SafeAdd(a, q), md5SafeAdd(x, t)), s), b);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5Ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
|
|
|
|
|
+ return md5Cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5Gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
|
|
|
|
|
+ return md5Cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5Hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
|
|
|
|
|
+ return md5Cmn(b ^ c ^ d, a, b, x, s, t);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5Ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
|
|
|
|
|
+ return md5Cmn(c ^ (b | (~d)), a, b, x, s, t);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function md5WordsToHex(words: number[]): string {
|
|
|
|
|
+ const hexChars = '0123456789abcdef';
|
|
|
|
|
+ let output = '';
|
|
|
|
|
+ for (let i = 0; i < words.length * 4; i++) {
|
|
|
|
|
+ const byte = (words[i >> 2] >>> ((i % 4) * 8)) & 0xff;
|
|
|
|
|
+ output += hexChars.charAt((byte >>> 4) & 0x0f) + hexChars.charAt(byte & 0x0f);
|
|
|
|
|
+ }
|
|
|
|
|
+ return output;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// TaskPool中使用的接口
|
|
// TaskPool中使用的接口
|
|
|
export interface TaskPrecreateRequest {
|
|
export interface TaskPrecreateRequest {
|
|
|
path: string;
|
|
path: string;
|
|
@@ -50,6 +100,16 @@ export interface TaskUploadPartResponse {
|
|
|
request_id?: number;
|
|
request_id?: number;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+interface TaskUploadServerInfo {
|
|
|
|
|
+ server: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface TaskLocateUploadResponse {
|
|
|
|
|
+ error_code: number;
|
|
|
|
|
+ error_msg?: string;
|
|
|
|
|
+ servers?: TaskUploadServerInfo[];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export interface TaskCreateFileRequest {
|
|
export interface TaskCreateFileRequest {
|
|
|
path: string;
|
|
path: string;
|
|
|
size: number;
|
|
size: number;
|
|
@@ -70,32 +130,101 @@ export interface TaskCreateFileResponse {
|
|
|
* @returns MD5十六进制字符串
|
|
* @returns MD5十六进制字符串
|
|
|
*/
|
|
*/
|
|
|
export async function simpleCalculateMD5(data: ArrayBuffer): Promise<string> {
|
|
export async function simpleCalculateMD5(data: ArrayBuffer): Promise<string> {
|
|
|
- try {
|
|
|
|
|
- // 使用简化的哈希算法,因为HarmonyOS可能没有直接暴露crypto模块
|
|
|
|
|
- // 这里使用一个简单的哈希函数作为替代
|
|
|
|
|
- const uint8Array = new Uint8Array(data);
|
|
|
|
|
- let hash = 0;
|
|
|
|
|
-
|
|
|
|
|
- for (let i = 0; i < uint8Array.length; i++) {
|
|
|
|
|
- const byte = uint8Array[i];
|
|
|
|
|
- hash = ((hash << 5) - hash) + byte;
|
|
|
|
|
- hash = hash & hash; // 转换为32位整数
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 转换为十六进制字符串并填充到32位,模拟MD5格式
|
|
|
|
|
- const hashStr = Math.abs(hash).toString(16).padStart(8, '0');
|
|
|
|
|
-
|
|
|
|
|
- // 为不同大小的数据生成更复杂的哈希
|
|
|
|
|
- const lengthHash = uint8Array.length.toString(16).padStart(8, '0');
|
|
|
|
|
- const firstByteHash = uint8Array.length > 0 ? uint8Array[0].toString(16).padStart(2, '0') : '00';
|
|
|
|
|
- const lastByteHash = uint8Array.length > 0 ? uint8Array[uint8Array.length - 1].toString(16).padStart(2, '0') : '00';
|
|
|
|
|
-
|
|
|
|
|
- // 组合生成一个32位的伪MD5哈希
|
|
|
|
|
- return (hashStr + lengthHash + firstByteHash + lastByteHash).substring(0, 32);
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- const err = error as Error;
|
|
|
|
|
- throw new Error(`MD5计算失败: ${err.message}`);
|
|
|
|
|
|
|
+ const bytes = new Uint8Array(data);
|
|
|
|
|
+ const x = md5ConvertToWords(bytes);
|
|
|
|
|
+ const originalBitLength = bytes.length * 8;
|
|
|
|
|
+
|
|
|
|
|
+ x[originalBitLength >> 5] = x[originalBitLength >> 5] || 0;
|
|
|
|
|
+ x[originalBitLength >> 5] |= 0x80 << (originalBitLength % 32);
|
|
|
|
|
+ const finalLength = (((originalBitLength + 64) >>> 9) << 4) + 14;
|
|
|
|
|
+ x[finalLength] = originalBitLength;
|
|
|
|
|
+
|
|
|
|
|
+ let a = 1732584193;
|
|
|
|
|
+ let b = -271733879;
|
|
|
|
|
+ let c = -1732584194;
|
|
|
|
|
+ let d = 271733878;
|
|
|
|
|
+
|
|
|
|
|
+ for (let i = 0; i < x.length; i += 16) {
|
|
|
|
|
+ const oldA = a;
|
|
|
|
|
+ const oldB = b;
|
|
|
|
|
+ const oldC = c;
|
|
|
|
|
+ const oldD = d;
|
|
|
|
|
+
|
|
|
|
|
+ a = md5Ff(a, b, c, d, x[i + 0] || 0, 7, -680876936);
|
|
|
|
|
+ d = md5Ff(d, a, b, c, x[i + 1] || 0, 12, -389564586);
|
|
|
|
|
+ c = md5Ff(c, d, a, b, x[i + 2] || 0, 17, 606105819);
|
|
|
|
|
+ b = md5Ff(b, c, d, a, x[i + 3] || 0, 22, -1044525330);
|
|
|
|
|
+ a = md5Ff(a, b, c, d, x[i + 4] || 0, 7, -176418897);
|
|
|
|
|
+ d = md5Ff(d, a, b, c, x[i + 5] || 0, 12, 1200080426);
|
|
|
|
|
+ c = md5Ff(c, d, a, b, x[i + 6] || 0, 17, -1473231341);
|
|
|
|
|
+ b = md5Ff(b, c, d, a, x[i + 7] || 0, 22, -45705983);
|
|
|
|
|
+ a = md5Ff(a, b, c, d, x[i + 8] || 0, 7, 1770035416);
|
|
|
|
|
+ d = md5Ff(d, a, b, c, x[i + 9] || 0, 12, -1958414417);
|
|
|
|
|
+ c = md5Ff(c, d, a, b, x[i + 10] || 0, 17, -42063);
|
|
|
|
|
+ b = md5Ff(b, c, d, a, x[i + 11] || 0, 22, -1990404162);
|
|
|
|
|
+ a = md5Ff(a, b, c, d, x[i + 12] || 0, 7, 1804603682);
|
|
|
|
|
+ d = md5Ff(d, a, b, c, x[i + 13] || 0, 12, -40341101);
|
|
|
|
|
+ c = md5Ff(c, d, a, b, x[i + 14] || 0, 17, -1502002290);
|
|
|
|
|
+ b = md5Ff(b, c, d, a, x[i + 15] || 0, 22, 1236535329);
|
|
|
|
|
+
|
|
|
|
|
+ a = md5Gg(a, b, c, d, x[i + 1] || 0, 5, -165796510);
|
|
|
|
|
+ d = md5Gg(d, a, b, c, x[i + 6] || 0, 9, -1069501632);
|
|
|
|
|
+ c = md5Gg(c, d, a, b, x[i + 11] || 0, 14, 643717713);
|
|
|
|
|
+ b = md5Gg(b, c, d, a, x[i + 0] || 0, 20, -373897302);
|
|
|
|
|
+ a = md5Gg(a, b, c, d, x[i + 5] || 0, 5, -701558691);
|
|
|
|
|
+ d = md5Gg(d, a, b, c, x[i + 10] || 0, 9, 38016083);
|
|
|
|
|
+ c = md5Gg(c, d, a, b, x[i + 15] || 0, 14, -660478335);
|
|
|
|
|
+ b = md5Gg(b, c, d, a, x[i + 4] || 0, 20, -405537848);
|
|
|
|
|
+ a = md5Gg(a, b, c, d, x[i + 9] || 0, 5, 568446438);
|
|
|
|
|
+ d = md5Gg(d, a, b, c, x[i + 14] || 0, 9, -1019803690);
|
|
|
|
|
+ c = md5Gg(c, d, a, b, x[i + 3] || 0, 14, -187363961);
|
|
|
|
|
+ b = md5Gg(b, c, d, a, x[i + 8] || 0, 20, 1163531501);
|
|
|
|
|
+ a = md5Gg(a, b, c, d, x[i + 13] || 0, 5, -1444681467);
|
|
|
|
|
+ d = md5Gg(d, a, b, c, x[i + 2] || 0, 9, -51403784);
|
|
|
|
|
+ c = md5Gg(c, d, a, b, x[i + 7] || 0, 14, 1735328473);
|
|
|
|
|
+ b = md5Gg(b, c, d, a, x[i + 12] || 0, 20, -1926607734);
|
|
|
|
|
+
|
|
|
|
|
+ a = md5Hh(a, b, c, d, x[i + 5] || 0, 4, -378558);
|
|
|
|
|
+ d = md5Hh(d, a, b, c, x[i + 8] || 0, 11, -2022574463);
|
|
|
|
|
+ c = md5Hh(c, d, a, b, x[i + 11] || 0, 16, 1839030562);
|
|
|
|
|
+ b = md5Hh(b, c, d, a, x[i + 14] || 0, 23, -35309556);
|
|
|
|
|
+ a = md5Hh(a, b, c, d, x[i + 1] || 0, 4, -1530992060);
|
|
|
|
|
+ d = md5Hh(d, a, b, c, x[i + 4] || 0, 11, 1272893353);
|
|
|
|
|
+ c = md5Hh(c, d, a, b, x[i + 7] || 0, 16, -155497632);
|
|
|
|
|
+ b = md5Hh(b, c, d, a, x[i + 10] || 0, 23, -1094730640);
|
|
|
|
|
+ a = md5Hh(a, b, c, d, x[i + 13] || 0, 4, 681279174);
|
|
|
|
|
+ d = md5Hh(d, a, b, c, x[i + 0] || 0, 11, -358537222);
|
|
|
|
|
+ c = md5Hh(c, d, a, b, x[i + 3] || 0, 16, -722521979);
|
|
|
|
|
+ b = md5Hh(b, c, d, a, x[i + 6] || 0, 23, 76029189);
|
|
|
|
|
+ a = md5Hh(a, b, c, d, x[i + 9] || 0, 4, -640364487);
|
|
|
|
|
+ d = md5Hh(d, a, b, c, x[i + 12] || 0, 11, -421815835);
|
|
|
|
|
+ c = md5Hh(c, d, a, b, x[i + 15] || 0, 16, 530742520);
|
|
|
|
|
+ b = md5Hh(b, c, d, a, x[i + 2] || 0, 23, -995338651);
|
|
|
|
|
+
|
|
|
|
|
+ a = md5Ii(a, b, c, d, x[i + 0] || 0, 6, -198630844);
|
|
|
|
|
+ d = md5Ii(d, a, b, c, x[i + 7] || 0, 10, 1126891415);
|
|
|
|
|
+ c = md5Ii(c, d, a, b, x[i + 14] || 0, 15, -1416354905);
|
|
|
|
|
+ b = md5Ii(b, c, d, a, x[i + 5] || 0, 21, -57434055);
|
|
|
|
|
+ a = md5Ii(a, b, c, d, x[i + 12] || 0, 6, 1700485571);
|
|
|
|
|
+ d = md5Ii(d, a, b, c, x[i + 3] || 0, 10, -1894986606);
|
|
|
|
|
+ c = md5Ii(c, d, a, b, x[i + 10] || 0, 15, -1051523);
|
|
|
|
|
+ b = md5Ii(b, c, d, a, x[i + 1] || 0, 21, -2054922799);
|
|
|
|
|
+ a = md5Ii(a, b, c, d, x[i + 8] || 0, 6, 1873313359);
|
|
|
|
|
+ d = md5Ii(d, a, b, c, x[i + 15] || 0, 10, -30611744);
|
|
|
|
|
+ c = md5Ii(c, d, a, b, x[i + 6] || 0, 15, -1560198380);
|
|
|
|
|
+ b = md5Ii(b, c, d, a, x[i + 13] || 0, 21, 1309151649);
|
|
|
|
|
+ a = md5Ii(a, b, c, d, x[i + 4] || 0, 6, -145523070);
|
|
|
|
|
+ d = md5Ii(d, a, b, c, x[i + 11] || 0, 10, -1120210379);
|
|
|
|
|
+ c = md5Ii(c, d, a, b, x[i + 2] || 0, 15, 718787259);
|
|
|
|
|
+ b = md5Ii(b, c, d, a, x[i + 9] || 0, 21, -343485551);
|
|
|
|
|
+
|
|
|
|
|
+ a = md5SafeAdd(a, oldA);
|
|
|
|
|
+ b = md5SafeAdd(b, oldB);
|
|
|
|
|
+ c = md5SafeAdd(c, oldC);
|
|
|
|
|
+ d = md5SafeAdd(d, oldD);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return md5WordsToHex([a, b, c, d]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -199,87 +328,43 @@ export async function simplePrecreateFile(token: string, request: TaskPrecreateR
|
|
|
* @param partSeq 分片序号
|
|
* @param partSeq 分片序号
|
|
|
* @param partData 分片数据
|
|
* @param partData 分片数据
|
|
|
*/
|
|
*/
|
|
|
-export async function simpleUploadFilePart(token: string, path: string, uploadId: string, partSeq: number, partData: ArrayBuffer): Promise<void> {
|
|
|
|
|
|
|
+export async function simpleUploadFilePart(uploadServer: string, token: string, path: string, uploadId: string, partSeq: number, partData: ArrayBuffer): Promise<void> {
|
|
|
try {
|
|
try {
|
|
|
- // 百度网盘分片上传的正确URL格式
|
|
|
|
|
- const url = 'https://pan.baidu.com/rest/2.0/xpan/file';
|
|
|
|
|
-
|
|
|
|
|
- // 转换路径为百度网盘要求的格式
|
|
|
|
|
const baiduPath = convertToBaiduPath(path);
|
|
const baiduPath = convertToBaiduPath(path);
|
|
|
-
|
|
|
|
|
- // 添加调试日志(在TaskPool中无法使用Logger,使用console替代)
|
|
|
|
|
- console.log(`分片${partSeq}上传 - 原始路径: ${path}, 转换后路径: ${baiduPath}, uploadid: ${uploadId}`);
|
|
|
|
|
-
|
|
|
|
|
- // 构建正确的查询参数(手动构建,因为URLSearchParams在TaskPool中可能不可用)
|
|
|
|
|
const params = [
|
|
const params = [
|
|
|
`method=upload`,
|
|
`method=upload`,
|
|
|
|
|
+ `type=tmpfile`,
|
|
|
`access_token=${encodeURIComponent(token)}`,
|
|
`access_token=${encodeURIComponent(token)}`,
|
|
|
`path=${encodeURIComponent(baiduPath)}`,
|
|
`path=${encodeURIComponent(baiduPath)}`,
|
|
|
`uploadid=${encodeURIComponent(uploadId)}`,
|
|
`uploadid=${encodeURIComponent(uploadId)}`,
|
|
|
`partseq=${partSeq}`
|
|
`partseq=${partSeq}`
|
|
|
].join('&');
|
|
].join('&');
|
|
|
|
|
|
|
|
- const requestUrl = `${url}?${params}`;
|
|
|
|
|
|
|
+ const requestUrl = `${uploadServer}/rest/2.0/pcs/superfile2?${params}`;
|
|
|
|
|
|
|
|
- // 构建multipart/form-data
|
|
|
|
|
const boundary = '----WebKitFormBoundary' + Math.random().toString(36).substr(2, 16);
|
|
const boundary = '----WebKitFormBoundary' + Math.random().toString(36).substr(2, 16);
|
|
|
- const uint8Array = new Uint8Array(partData);
|
|
|
|
|
-
|
|
|
|
|
- // 构建请求头部
|
|
|
|
|
- let formData = '';
|
|
|
|
|
- formData += `--${boundary}\r\n`;
|
|
|
|
|
- formData += `Content-Disposition: form-data; name="file"; filename="${baiduPath.split('/').pop()}"\r\n`;
|
|
|
|
|
- formData += `Content-Type: application/octet-stream\r\n\r\n`;
|
|
|
|
|
-
|
|
|
|
|
- // 编码头部
|
|
|
|
|
const encoder = new util.TextEncoder();
|
|
const encoder = new util.TextEncoder();
|
|
|
- const headerBytes = encoder.encode(formData);
|
|
|
|
|
-
|
|
|
|
|
- // 构建结尾
|
|
|
|
|
- const footerBytes = encoder.encode(`\r\n--${boundary}--\r\n`);
|
|
|
|
|
-
|
|
|
|
|
- // 创建完整的请求体
|
|
|
|
|
- const totalSize = headerBytes.length + uint8Array.length + footerBytes.length;
|
|
|
|
|
- const totalBuffer = new ArrayBuffer(totalSize);
|
|
|
|
|
- const totalUint8Array = new Uint8Array(totalBuffer);
|
|
|
|
|
-
|
|
|
|
|
- // 组合数据:头部 + 文件数据 + 结尾
|
|
|
|
|
- totalUint8Array.set(headerBytes, 0);
|
|
|
|
|
- totalUint8Array.set(uint8Array, headerBytes.length);
|
|
|
|
|
- totalUint8Array.set(footerBytes, headerBytes.length + uint8Array.length);
|
|
|
|
|
-
|
|
|
|
|
- interface UploadRequestHeader {
|
|
|
|
|
- 'Content-Type': string;
|
|
|
|
|
- 'Content-Length': string;
|
|
|
|
|
- 'User-Agent': string;
|
|
|
|
|
- 'Referer': string;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const header: UploadRequestHeader = {
|
|
|
|
|
- 'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
|
|
|
- 'Content-Length': totalSize.toString(),
|
|
|
|
|
- 'User-Agent': 'netdisk;P2SP;2.2.60.26',
|
|
|
|
|
- 'Referer': 'https://pan.baidu.com/disk/home'
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const headerPart = encoder.encode(
|
|
|
|
|
+ `--${boundary}\r\n` +
|
|
|
|
|
+ `Content-Disposition: form-data; name="file"; filename="${baiduPath.split('/').pop() || 'upload'}"\r\n` +
|
|
|
|
|
+ `Content-Type: application/octet-stream\r\n\r\n`
|
|
|
|
|
+ );
|
|
|
|
|
+ const footerPart = encoder.encode(`\r\n--${boundary}--\r\n`);
|
|
|
|
|
+ const payload = new Uint8Array(headerPart.length + partData.byteLength + footerPart.length);
|
|
|
|
|
+ payload.set(headerPart, 0);
|
|
|
|
|
+ payload.set(new Uint8Array(partData), headerPart.length);
|
|
|
|
|
+ payload.set(footerPart, headerPart.length + partData.byteLength);
|
|
|
|
|
|
|
|
const httpRequest = http.createHttp();
|
|
const httpRequest = http.createHttp();
|
|
|
-
|
|
|
|
|
- // 设置更长的超时时间,因为大文件上传可能需要更多时间
|
|
|
|
|
- interface HttpRequestOptions {
|
|
|
|
|
- method: http.RequestMethod;
|
|
|
|
|
- header: UploadRequestHeader;
|
|
|
|
|
- extraData: ArrayBuffer;
|
|
|
|
|
- readTimeout: number;
|
|
|
|
|
- connectTimeout: number;
|
|
|
|
|
- expectDataType: http.HttpDataType;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const options: HttpRequestOptions = {
|
|
|
|
|
|
|
+ const options: http.HttpRequestOptions = {
|
|
|
method: http.RequestMethod.POST,
|
|
method: http.RequestMethod.POST,
|
|
|
- header: header,
|
|
|
|
|
- extraData: totalBuffer,
|
|
|
|
|
- readTimeout: 60000, // 60秒读取超时
|
|
|
|
|
- connectTimeout: 30000, // 30秒连接超时
|
|
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
|
|
|
+ 'User-Agent': 'pan.baidu.com'
|
|
|
|
|
+ },
|
|
|
|
|
+ extraData: payload.buffer,
|
|
|
|
|
+ readTimeout: 60000,
|
|
|
|
|
+ connectTimeout: 30000,
|
|
|
expectDataType: http.HttpDataType.STRING
|
|
expectDataType: http.HttpDataType.STRING
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -404,4 +489,37 @@ export async function simpleCreateFile(token: string, request: TaskCreateFileReq
|
|
|
const err = error as Error;
|
|
const err = error as Error;
|
|
|
throw new Error(`创建文件失败: ${err.message}`);
|
|
throw new Error(`创建文件失败: ${err.message}`);
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export async function simpleLocateUploadServer(token: string, path: string, uploadId: string): Promise<string> {
|
|
|
|
|
+ const baiduPath = convertToBaiduPath(path);
|
|
|
|
|
+ const url = 'https://d.pcs.baidu.com/rest/2.0/pcs/file';
|
|
|
|
|
+ const params = [
|
|
|
|
|
+ `method=locateupload`,
|
|
|
|
|
+ `appid=250528`,
|
|
|
|
|
+ `access_token=${encodeURIComponent(token)}`,
|
|
|
|
|
+ `path=${encodeURIComponent(baiduPath)}`,
|
|
|
|
|
+ `uploadid=${encodeURIComponent(uploadId)}`,
|
|
|
|
|
+ `upload_version=2.0`
|
|
|
|
|
+ ].join('&');
|
|
|
|
|
+ const httpRequest = http.createHttp();
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await httpRequest.request(`${url}?${params}`, {
|
|
|
|
|
+ method: http.RequestMethod.GET,
|
|
|
|
|
+ expectDataType: http.HttpDataType.STRING,
|
|
|
|
|
+ readTimeout: 15000,
|
|
|
|
|
+ connectTimeout: 15000
|
|
|
|
|
+ });
|
|
|
|
|
+ if (response.responseCode !== 200 || !response.result) {
|
|
|
|
|
+ throw new Error(`locateupload失败: ${response.responseCode}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ const parsed = JSON.parse(response.result as string) as TaskLocateUploadResponse;
|
|
|
|
|
+ if (parsed.error_code !== 0 || !parsed.servers || parsed.servers.length === 0) {
|
|
|
|
|
+ throw new Error(`locateupload返回异常: ${parsed.error_code}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ const httpsServer = parsed.servers.find((server: TaskUploadServerInfo) => server.server.startsWith('https://'));
|
|
|
|
|
+ return (httpsServer || parsed.servers[0]).server;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ httpRequest.destroy();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|