@@ -49,7 +49,6 @@ class RedirectHandler {
4949 this . maxRedirections = maxRedirections
5050 this . handler = handler
5151 this . history = [ ]
52- this . redirectionLimitReached = false
5352
5453 if ( util . isStream ( this . opts . body ) ) {
5554 // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
@@ -99,27 +98,42 @@ class RedirectHandler {
9998 this . handler . onError ( error )
10099 }
101100
102- onHeaders ( statusCode , headers , resume , statusText ) {
103- this . location = this . history . length >= this . maxRedirections || util . isDisturbed ( this . opts . body )
104- ? null
105- : parseLocation ( statusCode , headers )
106-
101+ onHeaders ( statusCode , rawHeaders , resume , statusText ) {
107102 if ( this . opts . throwOnMaxRedirect && this . history . length >= this . maxRedirections ) {
108- if ( this . request ) {
109- this . request . abort ( new Error ( 'max redirects' ) )
103+ throw new Error ( 'max redirects' )
104+ }
105+
106+ // https://tools.ietf.org/html/rfc7231#section-6.4.2
107+ // https://fetch.spec.whatwg.org/#http-redirect-fetch
108+ // In case of HTTP 301 or 302 with POST, change the method to GET
109+ if ( ( statusCode === 301 || statusCode === 302 ) && this . opts . method === 'POST' ) {
110+ this . opts . method = 'GET'
111+ if ( util . isStream ( this . opts . body ) ) {
112+ util . destroy ( this . opts . body . on ( 'error' , noop ) )
110113 }
114+ this . opts . body = null
115+ }
111116
112- this . redirectionLimitReached = true
113- this . abort ( new Error ( 'max redirects' ) )
114- return
117+ // https://tools.ietf.org/html/rfc7231#section-6.4.4
118+ // In case of HTTP 303, always replace method to be either HEAD or GET
119+ if ( statusCode === 303 && this . opts . method !== 'HEAD' ) {
120+ this . opts . method = 'GET'
121+ if ( util . isStream ( this . opts . body ) ) {
122+ util . destroy ( this . opts . body . on ( 'error' , noop ) )
123+ }
124+ this . opts . body = null
115125 }
116126
127+ this . location = this . history . length >= this . maxRedirections || util . isDisturbed ( this . opts . body )
128+ ? null
129+ : parseLocation ( statusCode , rawHeaders )
130+
117131 if ( this . opts . origin ) {
118132 this . history . push ( new URL ( this . opts . path , this . opts . origin ) )
119133 }
120134
121135 if ( ! this . location ) {
122- return this . handler . onHeaders ( statusCode , headers , resume , statusText )
136+ return this . handler . onHeaders ( statusCode , rawHeaders , resume , statusText )
123137 }
124138
125139 const { origin, pathname, search } = util . parseURL ( new URL ( this . location , this . opts . origin && new URL ( this . opts . path , this . opts . origin ) ) )
@@ -133,23 +147,6 @@ class RedirectHandler {
133147 this . opts . origin = origin
134148 this . opts . maxRedirections = 0
135149 this . opts . query = null
136-
137- // https://tools.ietf.org/html/rfc7231#section-6.4.2
138- // https://fetch.spec.whatwg.org/#http-redirect-fetch
139- // In case of HTTP 301 or 302 with POST, change the method to GET
140- if ( ( statusCode === 301 || statusCode === 302 ) && this . opts . method === 'POST' ) {
141- this . opts . method = 'GET'
142- if ( util . isStream ( this . opts . body ) ) util . destroy ( this . opts . body . on ( 'error' , noop ) )
143- this . opts . body = null
144- }
145-
146- // https://tools.ietf.org/html/rfc7231#section-6.4.4
147- // In case of HTTP 303, always replace method to be either HEAD or GET
148- if ( statusCode === 303 && this . opts . method !== 'HEAD' ) {
149- this . opts . method = 'GET'
150- if ( util . isStream ( this . opts . body ) ) util . destroy ( this . opts . body . on ( 'error' , noop ) )
151- this . opts . body = null
152- }
153150 }
154151
155152 onData ( chunk ) {
@@ -203,14 +200,14 @@ class RedirectHandler {
203200 }
204201}
205202
206- function parseLocation ( statusCode , headers ) {
203+ function parseLocation ( statusCode , rawHeaders ) {
207204 if ( redirectableStatusCodes . indexOf ( statusCode ) === - 1 ) {
208205 return null
209206 }
210207
211- for ( let i = 0 ; i < headers . length ; i += 2 ) {
212- if ( headers [ i ] . length === 8 && util . headerNameToString ( headers [ i ] ) === 'location' ) {
213- return headers [ i + 1 ]
208+ for ( let i = 0 ; i < rawHeaders . length ; i += 2 ) {
209+ if ( rawHeaders [ i ] . length === 8 && util . headerNameToString ( rawHeaders [ i ] ) === 'location' ) {
210+ return rawHeaders [ i + 1 ]
214211 }
215212 }
216213}
0 commit comments