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" ;
4
3
5
- export function getHttpSegmentRequest (
6
- segment : Segment ,
4
+ export async function fulfillHttpSegmentRequest (
5
+ request : Request ,
7
6
settings : Pick < Settings , "httpRequestTimeout" >
8
- ) : Readonly < HttpRequest > {
7
+ ) {
9
8
const headers = new Headers ( ) ;
9
+ const { segment } = request ;
10
10
const { url, byteRange } = segment ;
11
11
12
12
if ( byteRange ) {
@@ -16,86 +16,61 @@ export function getHttpSegmentRequest(
16
16
}
17
17
18
18
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
- }
54
19
55
- throw error ;
56
- }
57
- } ;
20
+ const requestAbortTimeout = setTimeout ( ( ) => {
21
+ const errorType : HttpLoaderError [ "type" ] = "request-timeout" ;
22
+ abortController . abort ( errorType ) ;
23
+ } , settings . httpRequestTimeout ) ;
58
24
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 ) ;
67
28
} ;
68
- }
69
29
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 ,
81
35
} ) ;
82
- }
83
36
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
+ }
85
46
86
- const reader = response . body . getReader ( ) ;
87
- progress . startTimestamp = performance . now ( ) ;
47
+ if ( totalBytesString ) request . setTotalBytes ( + totalBytesString ) ;
88
48
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
+ }
94
73
}
95
-
96
- progress . totalBytes = progress . loadedBytes ;
97
-
98
- return Utils . joinChunks ( progress . chunks , progress . totalBytes ) ;
99
74
}
100
75
101
76
async function * readStream (
0 commit comments