*add modified downloadSkylink that uses the trust-needed endpoint and supports a path on the skylink, but also provides the raw response object
This commit is contained in:
parent
7d5578f5ee
commit
67285ccc08
91
src/util.ts
91
src/util.ts
|
@ -1,3 +1,15 @@
|
|||
import {
|
||||
addContextToErr,
|
||||
b64ToBuf,
|
||||
defaultPortalList,
|
||||
Err,
|
||||
objAsString,
|
||||
progressiveFetch,
|
||||
progressiveFetchResult,
|
||||
validSkylink,
|
||||
verifyDownloadResponse,
|
||||
} from "libskynet";
|
||||
|
||||
export function isIp(ip: string) {
|
||||
return /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
|
||||
ip
|
||||
|
@ -21,3 +33,82 @@ export const requestProxies = [
|
|||
{ type: "http", host: "skynetfree.net", port: 80 },
|
||||
{ type: "http", host: "skynetpro.net", port: 80 },
|
||||
];
|
||||
|
||||
export function getTld(hostname: string): string {
|
||||
return hostname.includes(".")
|
||||
? hostname.split(".")[hostname.split(".").length - 1]
|
||||
: hostname;
|
||||
}
|
||||
|
||||
export type FileDataType = {
|
||||
err: null;
|
||||
response: Response | null;
|
||||
fileData: Uint8Array;
|
||||
};
|
||||
|
||||
export function downloadSkylink(
|
||||
skylink: string,
|
||||
path?: string
|
||||
): Promise<[data: FileDataType, err: Err]> {
|
||||
return new Promise((resolve) => {
|
||||
// Get the Uint8Array of the input skylink.
|
||||
let [u8Link, errBTB] = b64ToBuf(skylink);
|
||||
if (errBTB !== null) {
|
||||
resolve([{} as any, addContextToErr(errBTB, "unable to decode skylink")]);
|
||||
return;
|
||||
}
|
||||
if (!validSkylink(u8Link)) {
|
||||
resolve([{} as any, "skylink appears to be invalid"]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the download call.
|
||||
let endpoint = "/" + skylink;
|
||||
if (path) {
|
||||
endpoint += path;
|
||||
}
|
||||
let fileDataPtr: FileDataType = {
|
||||
fileData: new Uint8Array(0),
|
||||
err: null,
|
||||
response: null,
|
||||
};
|
||||
let verifyFunction = function (response: Response): Promise<Err> {
|
||||
return verifyDownloadResponse(response, u8Link, fileDataPtr);
|
||||
};
|
||||
|
||||
// Perform the download call.
|
||||
progressiveFetch(endpoint, null, defaultPortalList, () =>
|
||||
Promise.resolve(null)
|
||||
).then((result: progressiveFetchResult) => {
|
||||
// Return an error if the call failed.
|
||||
if (result.success !== true) {
|
||||
// Check for a 404.
|
||||
for (let i = 0; i < result.responsesFailed.length; i++) {
|
||||
if (result.responsesFailed[i].status === 404) {
|
||||
resolve([{} as any, "404"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Error is not a 404, return the logs as the error.
|
||||
let err = objAsString(result.logs);
|
||||
resolve([
|
||||
{} as any,
|
||||
addContextToErr(err, "unable to complete download"),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
// Check if the portal is honest but the download is corrupt.
|
||||
if (fileDataPtr.err !== null) {
|
||||
resolve([
|
||||
{} as any,
|
||||
addContextToErr(fileDataPtr.err, "download is corrupt"),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
fileDataPtr.response = result.response;
|
||||
resolve([fileDataPtr, null]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Reference in New Issue