@@ -42,7 +42,6 @@ class RedirectHandler {
42
42
43
43
this . dispatch = dispatch
44
44
this . location = null
45
- this . abort = null
46
45
this . opts = { ...opts , maxRedirections : 0 } // opts must be a copy
47
46
this . maxRedirections = maxRedirections
48
47
this . handler = handler
@@ -83,20 +82,16 @@ class RedirectHandler {
83
82
}
84
83
}
85
84
86
- onConnect ( abort ) {
87
- this . abort = abort
88
- this . handler . onConnect ( abort , { history : this . history } )
89
- }
90
-
91
- onUpgrade ( statusCode , headers , socket ) {
92
- this . handler . onUpgrade ( statusCode , headers , socket )
85
+ onRequestStart ( controller , context ) {
86
+ this . location = null
87
+ this . handler . onRequestStart ?. ( controller , { ...context , history : this . history } )
93
88
}
94
89
95
- onError ( error ) {
96
- this . handler . onError ( error )
90
+ onRequestUpgrade ( controller , statusCode , headers , socket ) {
91
+ this . handler . onRequestUpgrade ?. ( controller , statusCode , headers , socket )
97
92
}
98
93
99
- onHeaders ( statusCode , rawHeaders , resume , statusText ) {
94
+ onResponseStart ( controller , statusCode , statusMessage , headers ) {
100
95
if ( this . opts . throwOnMaxRedirect && this . history . length >= this . maxRedirections ) {
101
96
throw new Error ( 'max redirects' )
102
97
}
@@ -122,16 +117,17 @@ class RedirectHandler {
122
117
this . opts . body = null
123
118
}
124
119
125
- this . location = this . history . length >= this . maxRedirections || util . isDisturbed ( this . opts . body )
120
+ this . location = this . history . length >= this . maxRedirections || util . isDisturbed ( this . opts . body ) || redirectableStatusCodes . indexOf ( statusCode ) === - 1
126
121
? null
127
- : parseLocation ( statusCode , rawHeaders )
122
+ : headers . location
128
123
129
124
if ( this . opts . origin ) {
130
125
this . history . push ( new URL ( this . opts . path , this . opts . origin ) )
131
126
}
132
127
133
128
if ( ! this . location ) {
134
- return this . handler . onHeaders ( statusCode , rawHeaders , resume , statusText )
129
+ this . handler . onResponseStart ?. ( controller , statusCode , statusMessage , headers )
130
+ return
135
131
}
136
132
137
133
const { origin, pathname, search } = util . parseURL ( new URL ( this . location , this . opts . origin && new URL ( this . opts . path , this . opts . origin ) ) )
@@ -140,14 +136,16 @@ class RedirectHandler {
140
136
// Remove headers referring to the original URL.
141
137
// By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers.
142
138
// https://tools.ietf.org/html/rfc7231#section-6.4
143
- this . opts . headers = cleanRequestHeaders ( this . opts . headers , statusCode === 303 , this . opts . origin !== origin )
139
+ this . opts . headers = this . opts . headers
140
+ ? cleanRequestHeaders ( this . opts . headers , statusCode === 303 , this . opts . origin !== origin )
141
+ : this . opts . headers
144
142
this . opts . path = path
145
143
this . opts . origin = origin
146
144
this . opts . maxRedirections = 0
147
145
this . opts . query = null
148
146
}
149
147
150
- onData ( chunk ) {
148
+ onResponseData ( controller , chunk ) {
151
149
if ( this . location ) {
152
150
/*
153
151
https://tools.ietf.org/html/rfc7231#section-6.4
@@ -167,11 +165,11 @@ class RedirectHandler {
167
165
servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it.
168
166
*/
169
167
} else {
170
- return this . handler . onData ( chunk )
168
+ this . handler . onResponseData ?. ( controller , chunk )
171
169
}
172
170
}
173
171
174
- onComplete ( trailers ) {
172
+ onResponseEnd ( controller , trailers ) {
175
173
if ( this . location ) {
176
174
/*
177
175
https://tools.ietf.org/html/rfc7231#section-6.4
@@ -181,68 +179,38 @@ class RedirectHandler {
181
179
182
180
See comment on onData method above for more detailed information.
183
181
*/
184
-
185
- this . location = null
186
- this . abort = null
187
-
188
182
this . dispatch ( this . opts , this )
189
183
} else {
190
- this . handler . onComplete ( trailers )
184
+ this . handler . onResponseEnd ( controller , trailers )
191
185
}
192
186
}
193
187
194
- onBodySent ( chunk ) {
195
- if ( this . handler . onBodySent ) {
196
- this . handler . onBodySent ( chunk )
197
- }
198
- }
199
- }
200
-
201
- function parseLocation ( statusCode , rawHeaders ) {
202
- if ( redirectableStatusCodes . indexOf ( statusCode ) === - 1 ) {
203
- return null
204
- }
205
-
206
- for ( let i = 0 ; i < rawHeaders . length ; i += 2 ) {
207
- if ( rawHeaders [ i ] . length === 8 && util . headerNameToString ( rawHeaders [ i ] ) === 'location' ) {
208
- return rawHeaders [ i + 1 ]
209
- }
188
+ onResponseError ( controller , error ) {
189
+ this . handler . onResponseError ?. ( controller , error )
210
190
}
211
191
}
212
192
213
193
// https://tools.ietf.org/html/rfc7231#section-6.4.4
214
- function shouldRemoveHeader ( header , removeContent , unknownOrigin ) {
215
- if ( header . length === 4 ) {
216
- return util . headerNameToString ( header ) === 'host'
194
+ function shouldRemoveHeader ( name , removeContent , unknownOrigin ) {
195
+ if ( name . length === 4 ) {
196
+ return name === 'host'
217
197
}
218
- if ( removeContent && util . headerNameToString ( header ) . startsWith ( 'content-' ) ) {
198
+ if ( removeContent && name . startsWith ( 'content-' ) ) {
219
199
return true
220
200
}
221
- if ( unknownOrigin && ( header . length === 13 || header . length === 6 || header . length === 19 ) ) {
222
- const name = util . headerNameToString ( header )
201
+ if ( unknownOrigin && ( name . length === 13 || name . length === 6 || name . length === 19 ) ) {
223
202
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
224
203
}
225
204
return false
226
205
}
227
206
228
207
// https://tools.ietf.org/html/rfc7231#section-6.4
229
208
function cleanRequestHeaders ( headers , removeContent , unknownOrigin ) {
230
- const ret = [ ]
231
- if ( Array . isArray ( headers ) ) {
232
- for ( let i = 0 ; i < headers . length ; i += 2 ) {
233
- if ( ! shouldRemoveHeader ( headers [ i ] , removeContent , unknownOrigin ) ) {
234
- ret . push ( headers [ i ] , headers [ i + 1 ] )
235
- }
236
- }
237
- } else if ( headers && typeof headers === 'object' ) {
238
- const entries = typeof headers [ Symbol . iterator ] === 'function' ? headers : Object . entries ( headers )
239
- for ( const [ key , value ] of entries ) {
240
- if ( ! shouldRemoveHeader ( key , removeContent , unknownOrigin ) ) {
241
- ret . push ( key , value )
242
- }
209
+ const ret = util . normalizeHeaders ( headers )
210
+ for ( const name of Object . keys ( ret ) ) {
211
+ if ( shouldRemoveHeader ( name , removeContent , unknownOrigin ) ) {
212
+ delete ret [ name ]
243
213
}
244
- } else {
245
- assert ( headers == null , 'headers must be an object or an array' )
246
214
}
247
215
return ret
248
216
}
0 commit comments