8000 ✨ Make downloadFiile work on browser · huggingface/huggingface.js@e60ab68 · GitHub
[go: up one dir, main page]

Skip to content

Commit e60ab68

Browse files
committed
✨ Make downloadFiile work on browser
1 parent 2e39636 commit e60ab68

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

packages/hub/src/lib/download-file.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,40 @@ export async function downloadFile(params: {
1616
raw?: boolean;
1717
revision?: string;
1818
credentials?: Credentials;
19+
hubUrl?: string;
1920
}): Promise<Response | null> {
20-
const url = `${HUB_URL}/${params.repo.type === "model" ? "" : `${params.repo.type}s/`}${params.repo.name}/${
21-
params.raw ? "raw" : "resolve"
22-
}/${encodeURIComponent(params.revision ?? "main")}/${params.path}`;
21+
const url = `${params.hubUrl ?? HUB_URL}/${params.repo.type === "model" ? "" : `${params.repo.type}s/`}${
22+
params.repo.name
23+
}/${params.raw ? "raw" : "resolve"}/${encodeURIComponent(params.revision ?? "main")}/${params.path}`;
2324

24-
const resp = await fetch(url, {
25+
let resp = await fetch(url, {
2526
headers: params.credentials
2627
? {
2728
Authorization: `Bearer ${params.credentials.accessToken}`,
2829
}
2930
: {},
3031
});
3132

33+
// On browser we need to do the redirects ourselves
34+
let redirects = 0;
35+
while (resp.status >= 300 && resp.status < 400) {
36+
if (++redirects >= 20) {
37+
throw new Error("Too many redirects");
38+
}
39+
40+
const newUrl = resp.headers.get("Location")!;
41+
const useCredentials = new URL(newUrl).host === new URL(url).host;
42+
43+
resp = await fetch(newUrl, {
44+
headers:
45+
useCredentials && params.credentials
46+
? {
47+
Authorization: `Bearer ${params.credentials.accessToken}`,
48+
}
49+
: {},
50+
});
51+
}
52+
3253
if (resp.status === 404 && resp.headers.get("X-Error-Code") === "EntryNotFound") {
3354
return null;
3455
} else if (!resp.ok) {

packages/hub/src/lib/file-download-info.ts

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface FileDownloadInfoOutput {
1313
/**
1414
* @returns null when the file doesn't exist
1515
*/
16-
export function fileDownloadInfo(params: {
16+
export async function fileDownloadInfo(params: {
1717
repo: RepoId;
1818
path: string;
1919
revision?: string;
@@ -28,43 +28,45 @@ export function fileDownloadInfo(params: {
2828
params.repo.name
2929
}/${params.raw ? "raw" : "resolve"}/${encodeURIComponent(params.revision ?? "main")}/${params.path}`;
3030

31-
return fileDownloadInfoInternal(url, params.credentials);
32-
}
33-
34-
async function fileDownloadInfoInternal(
35-
url: string,
36-
credentials?: Credentials,
37-
redirects = 0
38-
): Promise<FileDownloadInfoOutput | null> {
39-
if (redirects >= 20) {
40-
throw new Error("Too many redirects");
41-
}
42-
43-
const resp = await fetch(url, {
31+
let resp = await fetch(url, {
4432
method: "HEAD",
45-
headers: credentials
33+
headers: params.credentials
4634
? {
47-
Authorization: `Bearer ${credentials.accessToken}`,
35+
Authorization: `Bearer ${params.credentials.accessToken}`,
4836
}
4937
: {},
5038
redirect: "manual",
5139
});
5240

41+
let redirects = 0;
42+
while (resp.status >= 300 && resp.status < 400 && new URL(resp.headers.get("Location")!).host === new URL(url).host) {
43+
if (++redirects >= 20) {
44+
throw new Error("Too many redirects");
45+
}
46+
47+
resp = await fetch(url, {
48+
method: "HEAD",
49+
headers: params.credentials
50+
? {
51+
Authorization: `Bearer ${params.credentials.accessToken}`,
52+
}
53+
: {},
54+
redirect: "manual",
55+
});
56+
}
57+
5358
if (resp.status === 404 && resp.headers.get("X-Error-Code") === "EntryNotFound") {
5459
return null;
5560
}
5661

5762
let isLfs = false;
58-
if (resp.status >= 300 && resp.status < 400) {
59-
if (resp.headers.get("Location")?.startsWith(HUB_URL)) {
60-
// can happen on repo name change
61-
return fileDownloadInfoInternal(resp.headers.get("Location")!, credentials, redirects + 1);
62-
}
6363

64-
if (!resp.headers.has("X-Linked-Size")) {
64+
if (resp.status >= 300 && resp.status < 400) {
65+
if (resp.headers.has("X-Linked-Size")) {
66+
isLfs = true;
67+
} else {
6568
throw new Error("Invalid response from server: redirect to external server should have X-Linked-Size header");
6669
}
67-
isLfs = true;
6870
} else if (!resp.ok) {
6971
throw await createApiError(resp);
7072
}

0 commit comments

Comments
 (0)
0