@@ -5,30 +5,27 @@ import { MessageType } from '../message'
5
5
6
6
const debug = registerDebug ( 'msl:http-source' )
7
7
8
- interface Headers {
9
- [ key : string ] : string
10
- }
11
-
12
8
export interface HttpConfig {
13
9
uri : string
14
- headers ?: Headers
10
+ options ?: RequestInit
15
11
}
16
12
17
13
export class HttpSource extends Source {
18
14
public uri : string
19
- public headers ?: Headers
15
+ public options ?: RequestInit
20
16
public length ?: number
21
17
22
18
private _reader ?: ReadableStreamDefaultReader < Uint8Array >
19
+ private _abortController ?: AbortController
20
+ private _allDone : boolean
23
21
24
22
/**
25
23
* Create an HTTP component.
26
24
*
27
25
* The constructor sets a single readable stream from a fetch.
28
26
*/
29
27
constructor ( config : HttpConfig ) {
30
- const { uri, headers } = config
31
-
28
+ const { uri, options } = config
32
29
/**
33
30
* Set up an incoming stream and attach it to the socket.
34
31
*/
@@ -56,16 +53,23 @@ export class HttpSource extends Source {
56
53
}
57
54
58
55
this . uri = uri
59
- this . headers = headers
56
+ this . options = options
57
+ this . _allDone = false
60
58
}
61
59
62
60
play ( ) : void {
63
61
if ( this . uri === undefined ) {
64
62
throw new Error ( 'cannot start playing when there is no URI' )
65
63
}
66
64
65
+ this . _abortController = new AbortController ( )
66
+
67
67
this . length = 0
68
- fetch ( this . uri , { headers : this . headers } )
68
+ fetch ( this . uri , {
69
+ credentials : 'include' ,
70
+ signal : this . _abortController . signal ,
71
+ ...this . options ,
72
+ } )
69
73
. then ( ( rsp ) => {
70
74
if ( rsp . body === null ) {
71
75
throw new Error ( 'empty response body' )
@@ -75,41 +79,57 @@ export class HttpSource extends Source {
75
79
this . _pull ( )
76
80
} )
77
81
. catch ( ( err ) => {
78
- throw new Error ( err )
82
+ console . error ( 'http-source: fetch failed: ' , err )
79
83
} )
80
84
}
81
85
86
+ abort ( ) : void {
87
+ this . _reader &&
88
+ this . _reader . cancel ( ) . catch ( ( err ) => {
89
+ console . log ( 'http-source: cancel reader failed: ' , err )
90
+ } )
91
+ this . _abortController && this . _abortController . abort ( )
92
+ }
93
+
82
94
_pull ( ) : void {
83
95
if ( this . _reader === undefined ) {
84
96
return
85
97
}
86
98
87
- this . _reader . read ( ) . then ( ( { done, value } ) => {
88
- if ( done ) {
89
- debug ( 'fetch completed, total downloaded: ' , this . length , ' bytes' )
90
- this . incoming . push ( null )
91
- return
92
- }
93
- if ( value === undefined ) {
94
- throw new Error ( 'expected value to be defined' )
95
- }
96
- if ( this . length === undefined ) {
97
- throw new Error ( 'expected length to be defined' )
98
- }
99
- this . length += value . length
100
- const buffer = Buffer . from ( value )
101
- if ( ! this . incoming . push ( { data : buffer , type : MessageType . RAW } ) ) {
102
- // Something happened down stream that it is no longer processing the
103
- // incoming data, and the stream buffer got full.
104
- // This could be because we are downloading too much data at once,
105
- // or because the downstream is frozen. The latter is most likely
106
- // when dealing with a live stream (as in that case we would expect
107
- // downstream to be able to handle the data).
108
- debug ( 'downstream back pressure: pausing read' )
109
- } else {
110
- // It's ok to read more data
111
- this . _pull ( )
112
- }
113
- } )
99
+ this . _reader
100
+ . read ( )
101
+ . then ( ( { done, value } ) => {
102
+ if ( done ) {
103
+ if ( ! this . _allDone ) {
104
+ debug ( 'fetch completed, total downloaded: ' , this . length , ' bytes' )
105
+ this . incoming . push ( null )
106
+ }
107
+ this . _allDone = true
108
+ return
109
+ }
110
+ if ( value === undefined ) {
111
+ throw new Error ( 'expected value to be defined' )
112
+ }
113
+ if ( this . length === undefined ) {
114
+ throw new Error ( 'expected length to be defined' )
115
+ }
116
+ this . length += value . length
117
+ const buffer = Buffer . from ( value )
118
+ if ( ! this . incoming . push ( { data : buffer , type : MessageType . RAW } ) ) {
119
+ // Something happened down stream that it is no longer processing the
120
+ // incoming data, and the stream buffer got full.
121
+ // This could be because we are downloading too much data at once,
122
+ // or because the downstream is frozen. The latter is most likely
123
+ // when dealing with a live stream (as in that case we would expect
124
+ // downstream to be able to handle the data).
125
+ debug ( 'downstream back pressure: pausing read' )
126
+ } else {
127
+ // It's ok to read more data
128
+ this . _pull ( )
129
+ }
130
+ } )
131
+ . catch ( ( err ) => {
132
+ console . error ( 'http-source: read failed: ' , err )
133
+ } )
114
134
}
115
135
}
0 commit comments