react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / request / lib / redirect.js
81141 views'use strict'12var url = require('url')3var isUrl = /^https?:/45function Redirect (request) {6this.request = request7this.followRedirect = true8this.followRedirects = true9this.followAllRedirects = false10this.allowRedirect = function () {return true}11this.maxRedirects = 1012this.redirects = []13this.redirectsFollowed = 014this.removeRefererHeader = false15}1617Redirect.prototype.onRequest = function (options) {18var self = this1920if (options.maxRedirects !== undefined) {21self.maxRedirects = options.maxRedirects22}23if (typeof options.followRedirect === 'function') {24self.allowRedirect = options.followRedirect25}26if (options.followRedirect !== undefined) {27self.followRedirects = !!options.followRedirect28}29if (options.followAllRedirects !== undefined) {30self.followAllRedirects = options.followAllRedirects31}32if (self.followRedirects || self.followAllRedirects) {33self.redirects = self.redirects || []34}35if (options.removeRefererHeader !== undefined) {36self.removeRefererHeader = options.removeRefererHeader37}38}3940Redirect.prototype.redirectTo = function (response) {41var self = this42, request = self.request4344var redirectTo = null45if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) {46var location = response.caseless.get('location')47request.debug('redirect', location)4849if (self.followAllRedirects) {50redirectTo = location51} else if (self.followRedirects) {52switch (request.method) {53case 'PATCH':54case 'PUT':55case 'POST':56case 'DELETE':57// Do not follow redirects58break59default:60redirectTo = location61break62}63}64} else if (response.statusCode === 401) {65var authHeader = request._auth.onResponse(response)66if (authHeader) {67request.setHeader('authorization', authHeader)68redirectTo = request.uri69}70}71return redirectTo72}7374Redirect.prototype.onResponse = function (response) {75var self = this76, request = self.request7778var redirectTo = self.redirectTo(response)79if (!redirectTo || !self.allowRedirect.call(request, response)) {80return false81}8283request.debug('redirect to', redirectTo)8485// ignore any potential response body. it cannot possibly be useful86// to us at this point.87// response.resume should be defined, but check anyway before calling. Workaround for browserify.88if (response.resume) {89response.resume()90}9192if (self.redirectsFollowed >= self.maxRedirects) {93request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href))94return false95}96self.redirectsFollowed += 19798if (!isUrl.test(redirectTo)) {99redirectTo = url.resolve(request.uri.href, redirectTo)100}101102var uriPrev = request.uri103request.uri = url.parse(redirectTo)104105// handle the case where we change protocol from https to http or vice versa106if (request.uri.protocol !== uriPrev.protocol) {107request._updateProtocol()108}109110self.redirects.push(111{ statusCode : response.statusCode112, redirectUri: redirectTo113}114)115if (self.followAllRedirects && response.statusCode !== 401 && response.statusCode !== 307) {116request.method = 'GET'117}118// request.method = 'GET' // Force all redirects to use GET || commented out fixes #215119delete request.src120delete request.req121delete request.agent122delete request._started123if (response.statusCode !== 401 && response.statusCode !== 307) {124// Remove parameters from the previous response, unless this is the second request125// for a server that requires digest authentication.126delete request.body127delete request._form128if (request.headers) {129request.removeHeader('host')130request.removeHeader('content-type')131request.removeHeader('content-length')132if (request.uri.hostname !== request.originalHost.split(':')[0]) {133// Remove authorization if changing hostnames (but not if just134// changing ports or protocols). This matches the behavior of curl:135// https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710136request.removeHeader('authorization')137}138}139}140141if (!self.removeRefererHeader) {142request.setHeader('referer', request.uri.href)143}144145request.emit('redirect')146147request.init()148149return true150}151152exports.Redirect = Redirect153154155