| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 | 
							- 'use strict'
 
- var url = require('url')
 
- var isUrl = /^https?:/
 
- function Redirect (request) {
 
-   this.request = request
 
-   this.followRedirect = true
 
-   this.followRedirects = true
 
-   this.followAllRedirects = false
 
-   this.followOriginalHttpMethod = false
 
-   this.allowRedirect = function () { return true }
 
-   this.maxRedirects = 10
 
-   this.redirects = []
 
-   this.redirectsFollowed = 0
 
-   this.removeRefererHeader = false
 
- }
 
- Redirect.prototype.onRequest = function (options) {
 
-   var self = this
 
-   if (options.maxRedirects !== undefined) {
 
-     self.maxRedirects = options.maxRedirects
 
-   }
 
-   if (typeof options.followRedirect === 'function') {
 
-     self.allowRedirect = options.followRedirect
 
-   }
 
-   if (options.followRedirect !== undefined) {
 
-     self.followRedirects = !!options.followRedirect
 
-   }
 
-   if (options.followAllRedirects !== undefined) {
 
-     self.followAllRedirects = options.followAllRedirects
 
-   }
 
-   if (self.followRedirects || self.followAllRedirects) {
 
-     self.redirects = self.redirects || []
 
-   }
 
-   if (options.removeRefererHeader !== undefined) {
 
-     self.removeRefererHeader = options.removeRefererHeader
 
-   }
 
-   if (options.followOriginalHttpMethod !== undefined) {
 
-     self.followOriginalHttpMethod = options.followOriginalHttpMethod
 
-   }
 
- }
 
- Redirect.prototype.redirectTo = function (response) {
 
-   var self = this
 
-   var request = self.request
 
-   var redirectTo = null
 
-   if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) {
 
-     var location = response.caseless.get('location')
 
-     request.debug('redirect', location)
 
-     if (self.followAllRedirects) {
 
-       redirectTo = location
 
-     } else if (self.followRedirects) {
 
-       switch (request.method) {
 
-         case 'PATCH':
 
-         case 'PUT':
 
-         case 'POST':
 
-         case 'DELETE':
 
-           // Do not follow redirects
 
-           break
 
-         default:
 
-           redirectTo = location
 
-           break
 
-       }
 
-     }
 
-   } else if (response.statusCode === 401) {
 
-     var authHeader = request._auth.onResponse(response)
 
-     if (authHeader) {
 
-       request.setHeader('authorization', authHeader)
 
-       redirectTo = request.uri
 
-     }
 
-   }
 
-   return redirectTo
 
- }
 
- Redirect.prototype.onResponse = function (response) {
 
-   var self = this
 
-   var request = self.request
 
-   var redirectTo = self.redirectTo(response)
 
-   if (!redirectTo || !self.allowRedirect.call(request, response)) {
 
-     return false
 
-   }
 
-   request.debug('redirect to', redirectTo)
 
-   // ignore any potential response body.  it cannot possibly be useful
 
-   // to us at this point.
 
-   // response.resume should be defined, but check anyway before calling. Workaround for browserify.
 
-   if (response.resume) {
 
-     response.resume()
 
-   }
 
-   if (self.redirectsFollowed >= self.maxRedirects) {
 
-     request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href))
 
-     return false
 
-   }
 
-   self.redirectsFollowed += 1
 
-   if (!isUrl.test(redirectTo)) {
 
-     redirectTo = url.resolve(request.uri.href, redirectTo)
 
-   }
 
-   var uriPrev = request.uri
 
-   request.uri = url.parse(redirectTo)
 
-   // handle the case where we change protocol from https to http or vice versa
 
-   if (request.uri.protocol !== uriPrev.protocol) {
 
-     delete request.agent
 
-   }
 
-   self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo })
 
-   if (self.followAllRedirects && request.method !== 'HEAD' &&
 
-     response.statusCode !== 401 && response.statusCode !== 307) {
 
-     request.method = self.followOriginalHttpMethod ? request.method : 'GET'
 
-   }
 
-   // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215
 
-   delete request.src
 
-   delete request.req
 
-   delete request._started
 
-   if (response.statusCode !== 401 && response.statusCode !== 307) {
 
-     // Remove parameters from the previous response, unless this is the second request
 
-     // for a server that requires digest authentication.
 
-     delete request.body
 
-     delete request._form
 
-     if (request.headers) {
 
-       request.removeHeader('host')
 
-       request.removeHeader('content-type')
 
-       request.removeHeader('content-length')
 
-       if (request.uri.hostname !== request.originalHost.split(':')[0]) {
 
-         // Remove authorization if changing hostnames (but not if just
 
-         // changing ports or protocols).  This matches the behavior of curl:
 
-         // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710
 
-         request.removeHeader('authorization')
 
-       }
 
-     }
 
-   }
 
-   if (!self.removeRefererHeader) {
 
-     request.setHeader('referer', uriPrev.href)
 
-   }
 
-   request.emit('redirect')
 
-   request.init()
 
-   return true
 
- }
 
- exports.Redirect = Redirect
 
 
  |