Skip to content

Commit 64aff00

Browse files
authored
Merge pull request #1487 from easyops-cn/steve/range-request-flag
fix(): detect multipart range request support
2 parents 32803d7 + 39e67db commit 64aff00

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

bricks/icons/src/fa-icon/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ async function resolveIconDefinition(
2424
id: string
2525
): Promise<IconDefinition | null> {
2626
// istanbul ignore next: experimental
27-
if (supportsMultipartRangeRequest) {
28-
try {
27+
try {
28+
if (await supportsMultipartRangeRequest()) {
2929
const content = await faRangeRequest.fetch(id);
3030
return JSON.parse(content);
31-
} catch (error) {
32-
// eslint-disable-next-line no-console
33-
console.warn("Failed to fetch icon by range:", id, error);
34-
// Fallback to traditional fetch.
3531
}
32+
} catch (error) {
33+
// eslint-disable-next-line no-console
34+
console.warn("Failed to fetch icon by range:", id, error);
35+
// Fallback to traditional fetch.
3636
}
3737

3838
try {

bricks/icons/src/shared/RangeRequest.ts

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// istanbul ignore file: experimental
22
import { has } from "lodash";
3+
import { getRuntime } from "@next-core/runtime";
34
import antdIcons from "../antd-icon/generated/icons.json";
45
import easyopsIcons from "../easyops-icon/generated/icons.json";
56
import faIcons from "../fa-icon/generated/icons.json";
67
import antdRanges from "../antd-icon/generated/ranges.json";
78
import faRanges from "../fa-icon/generated/ranges.json";
89
import easyopsRanges from "../easyops-icon/generated/ranges.json";
9-
import { getRuntime } from "@next-core/runtime";
1010

1111
const publicPath =
1212
process.env.NODE_ENV === "test" ? "" : __webpack_public_path__;
@@ -29,10 +29,69 @@ const SETTINGS_MAP = {
2929
},
3030
} as unknown as Record<string, Settings>;
3131

32-
export let supportsMultipartRangeRequest =
32+
const TEST_URL = `${publicPath}manifest.json`;
33+
34+
let supports =
3335
process.env.NODE_ENV !== "test" &&
3436
getRuntime?.()?.getFeatureFlags()["icons-multipart-range-request"];
3537

38+
const supportsPromise = new Promise<boolean>((resolve) => {
39+
if (!supports) {
40+
resolve(false);
41+
return;
42+
}
43+
44+
const waitSeconds = 3;
45+
const timeout = setTimeout(() => {
46+
// eslint-disable-next-line no-console
47+
console.warn(
48+
`Multipart range request test timed out after ${waitSeconds} seconds`
49+
);
50+
resolve(false);
51+
}, waitSeconds * 1000);
52+
53+
(async () => {
54+
const res = await fetch(TEST_URL, {
55+
headers: {
56+
Range: `bytes=0-1, 3-4`,
57+
},
58+
});
59+
60+
if (!res.ok || res.status !== 206) {
61+
// eslint-disable-next-line no-console
62+
console.warn(
63+
`Multipart range request test failed with status: ${res.status} ${res.statusText}`
64+
);
65+
resolve(false);
66+
clearTimeout(timeout);
67+
return;
68+
}
69+
70+
const contentType = res.headers.get("Content-Type");
71+
if (
72+
!contentType?.match(/\bmultipart\/byteranges;\s*\S*?boundary=([^\s;]+)/)
73+
) {
74+
// eslint-disable-next-line no-console
75+
console.warn(
76+
`Multipart range request test failed with unexpected Content-Type: "${contentType}"`
77+
);
78+
resolve(false);
79+
clearTimeout(timeout);
80+
return;
81+
}
82+
83+
resolve(true);
84+
clearTimeout(timeout);
85+
})();
86+
});
87+
88+
export async function supportsMultipartRangeRequest() {
89+
if (!supports) {
90+
return false;
91+
}
92+
return await supportsPromise;
93+
}
94+
3695
type Lib = "antd" | "fa" | "easyops";
3796

3897
interface Settings {
@@ -378,7 +437,6 @@ async function request(
378437
headers: {
379438
Range: `bytes=${bytes.join(", ")}`,
380439
},
381-
cache: "force-cache",
382440
});
383441

384442
if (!response.ok) {
@@ -394,7 +452,7 @@ async function request(
394452
console.error(
395453
`Unexpected response status: ${response.status} ${response.statusText}`
396454
);
397-
supportsMultipartRangeRequest = false;
455+
supports = false;
398456
return;
399457
}
400458

@@ -406,7 +464,7 @@ async function request(
406464
if (!matches) {
407465
// eslint-disable-next-line no-console
408466
console.error(`Unexpected Content-Type: "${contentType}"`);
409-
supportsMultipartRangeRequest = false;
467+
supports = false;
410468
return;
411469
}
412470

bricks/icons/src/shared/SvgCache.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ async function resolveIcon(
3131
let content: string | undefined;
3232

3333
// istanbul ignore next: experimental
34-
if (options?.id && supportsMultipartRangeRequest) {
35-
try {
34+
try {
35+
if (options?.id && (await supportsMultipartRangeRequest())) {
3636
const rangeRequest =
3737
options.lib === "easyops" ? easyopsRangeRequest : antdRangeRequest;
3838
content = await rangeRequest.fetch(options.id);
39-
} catch {
40-
// Fallback to traditional fetch.
4139
}
40+
} catch {
41+
// Fallback to traditional fetch.
4242
}
4343

4444
if (!content) {

0 commit comments

Comments
 (0)