Skip to content

Commit e019870

Browse files
committed
Create Request class.
1 parent 7408c87 commit e019870

File tree

8 files changed

+393
-425
lines changed

8 files changed

+393
-425
lines changed

packages/p2p-media-loader-core/src/http-loader.ts

Lines changed: 52 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { Segment, Settings } from "./types";
2-
import { HttpRequest, LoadProgress } from "./request-container";
3-
import * as Utils from "./utils/utils";
1+
import { Settings } from "./types";
2+
import { Request } from "./request-container";
43

5-
export function getHttpSegmentRequest(
6-
segment: Segment,
4+
export async function fulfillHttpSegmentRequest(
5+
request: Request,
76
settings: Pick<Settings, "httpRequestTimeout">
8-
): Readonly<HttpRequest> {
7+
) {
98
const headers = new Headers();
9+
const { segment } = request;
1010
const { url, byteRange } = segment;
1111

1212
if (byteRange) {
@@ -16,86 +16,61 @@ export function getHttpSegmentRequest(
1616
}
1717

1818
const abortController = new AbortController();
19-
const progress: LoadProgress = {
20-
loadedBytes: 0,
21-
startTimestamp: performance.now(),
22-
chunks: [],
23-
};
24-
const loadSegmentData = async () => {
25-
const requestAbortTimeout = setTimeout(() => {
26-
const errorType: HttpLoaderError["type"] = "request-timeout";
27-
abortController.abort(errorType);
28-
}, settings.httpRequestTimeout);
29-
30-
try {
31-
const response = await window.fetch(url, {
32-
headers,
33-
signal: abortController.signal,
34-
});
35-
36-
if (response.ok) {
37-
const data = await getDataPromiseAndMonitorProgress(response, progress);
38-
clearTimeout(requestAbortTimeout);
39-
return data;
40-
}
41-
throw new HttpLoaderError("fetch-error", response.statusText);
42-
} catch (error) {
43-
if (error instanceof Error) {
44-
if ((error.name as HttpLoaderError["type"]) === "manual-abort") {
45-
throw new HttpLoaderError("manual-abort");
46-
}
47-
if ((error.name as HttpLoaderError["type"]) === "request-timeout") {
48-
throw new HttpLoaderError("request-timeout");
49-
}
50-
if (!(error instanceof HttpLoaderError)) {
51-
throw new HttpLoaderError("fetch-error", error.message);
52-
}
53-
}
5419

55-
throw error;
56-
}
57-
};
20+
const requestAbortTimeout = setTimeout(() => {
21+
const errorType: HttpLoaderError["type"] = "request-timeout";
22+
abortController.abort(errorType);
23+
}, settings.httpRequestTimeout);
5824

59-
return {
60-
type: "http",
61-
promise: loadSegmentData(),
62-
progress,
63-
abort: () => {
64-
const abortErrorType: HttpLoaderError["type"] = "manual-abort";
65-
abortController.abort(abortErrorType);
66-
},
25+
const abortManually = () => {
26+
const abortErrorType: HttpLoaderError["type"] = "manual-abort";
27+
abortController.abort(abortErrorType);
6728
};
68-
}
6929

70-
async function getDataPromiseAndMonitorProgress(
71-
response: Response,
72-
progress: LoadProgress
73-
): Promise<ArrayBuffer> {
74-
const totalBytesString = response.headers.get("Content-Length");
75-
if (!response.body) {
76-
return response.arrayBuffer().then((data) => {
77-
progress.loadedBytes = data.byteLength;
78-
progress.totalBytes = data.byteLength;
79-
progress.lastLoadedChunkTimestamp = performance.now();
80-
return data;
30+
const requestControls = request.start("http", abortManually);
31+
try {
32+
const fetchResponse = await window.fetch(url, {
33+
headers,
34+
signal: abortController.signal,
8135
});
82-
}
8336

84-
if (totalBytesString) progress.totalBytes = +totalBytesString;
37+
if (fetchResponse.ok) {
38+
const totalBytesString = fetchResponse.headers.get("Content-Length");
39+
if (!fetchResponse.body) {
40+
fetchResponse.arrayBuffer().then((data) => {
41+
requestControls.addLoadedChunk(data);
42+
requestControls.completeOnSuccess();
43+
});
44+
return;
45+
}
8546

86-
const reader = response.body.getReader();
87-
progress.startTimestamp = performance.now();
47+
if (totalBytesString) request.setTotalBytes(+totalBytesString);
8848

89-
progress.chunks = [];
90-
for await (const chunk of readStream(reader)) {
91-
progress.chunks.push(chunk);
92-
progress.loadedBytes += chunk.length;
93-
progress.lastLoadedChunkTimestamp = performance.now();
49+
const reader = fetchResponse.body.getReader();
50+
for await (const chunk of readStream(reader)) {
51+
requestControls.addLoadedChunk(chunk);
52+
}
53+
requestControls.completeOnSuccess();
54+
clearTimeout(requestAbortTimeout);
55+
}
56+
throw new HttpLoaderError("fetch-error", fetchResponse.statusText);
57+
} catch (error) {
58+
if (error instanceof Error) {
59+
let httpLoaderError: HttpLoaderError;
60+
if ((error.name as HttpLoaderError["type"]) === "manual-abort") {
61+
httpLoaderError = new HttpLoaderError("manual-abort");
62+
} else if (
63+
(error.name as HttpLoaderError["type"]) === "request-timeout"
64+
) {
65+
httpLoaderError = new HttpLoaderError("request-timeout");
66+
} else if (!(error instanceof HttpLoaderError)) {
67+
httpLoaderError = new HttpLoaderError("fetch-error", error.message);
68+
} else {
69+
httpLoaderError = error;
70+
}
71+
requestControls.cancelOnError(httpLoaderError);
72+
}
9473
}
95-
96-
progress.totalBytes = progress.loadedBytes;
97-
98-
return Utils.joinChunks(progress.chunks, progress.totalBytes);
9974
}
10075

10176
async function* readStream(

0 commit comments

Comments
 (0)