Repository: sindresorhus/got
Pull request #166 (2016-02-02 05:13:51)

Added option to toggle automatic following redirects
Hi @floatdrop and @sindresorhus,

I'm opening this PR with the goal of illustrating what such an option as described on #165 would look like.

Please review at your own discretion. 

Thanks in advance :+1: 

knksmith57: +1
sindresorhus: After much thinking I'm :+1: on this. @floatdrop You ok with this?
floatdrop: @sindresorhus how about merge this with `maxRedirects` option? For example `-1` in `maxRedirects` will disable redirect following.
sindresorhus: @floatdrop We don't have a `maxRedirects` option. ?
floatdrop: @sindresorhus yep, just an idea.
sindresorhus: I'm not a big fan of `-1` input, and in that case it could just be `0`, but still, I don't really see the need of a `maxRedirects` option, and since we have neither at the moment, I'd rather just expose a `followRedirects` option that is actually requested by multiple people.

Patch:
diff --git a/index.js b/index.js
index 0a43b9b..1ad357c 100644
--- a/index.js
+++ b/index.js
@@ -33,7 +33,7 @@ function requestAsEventEmitter(opts) {
 		const req = fn.request(opts, res => {
 			const statusCode = res.statusCode;
 
-			if (isRedirect(statusCode) && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) {
+			if (isRedirect(statusCode) && opts.followRedirect && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) {
 				res.resume();
 
 				if (++redirectCount > 10) {
@@ -98,6 +98,7 @@ function asPromise(opts) {
 				.catch(err => reject(new got.ReadError(err, opts)))
 				.then(data => {
 					const statusCode = res.statusCode;
+					const limitStatusCode = opts.followRedirect ? 299 : 399;
 
 					res.body = data;
 
@@ -109,7 +110,7 @@ function asPromise(opts) {
 						}
 					}
 
-					if (statusCode < 200 || statusCode > 299) {
+					if (statusCode < 200 || statusCode > limitStatusCode) {
 						throw new got.HTTPError(statusCode, opts);
 					}
 
@@ -268,6 +269,10 @@ function normalizeArguments(url, opts) {
 		};
 	}
 
+	if (opts.followRedirect === undefined) {
+		opts.followRedirect = true;
+	}
+
 	return opts;
 }
 
diff --git a/readme.md b/readme.md
index d2ed519..9552945 100644
--- a/readme.md
+++ b/readme.md
@@ -124,6 +124,13 @@ Option accepts `function` with `retry` and `error` arguments. Function must retu
 
 **Note:** if `retries` is `number`, `ENOTFOUND` and `ENETUNREACH` error will not be retried (see full list in [`is-retry-allowed`](https://github.com/floatdrop/is-retry-allowed/blob/master/index.js#L12) module).
 
+###### followRedirect
+
+Type: `boolean`  
+Default: `true`
+
+Defines if redirect responses should be followed automatically.
+
 
 #### Streams
 


Test patch:
diff --git a/test/redirects.js b/test/redirects.js
index ceceb27..65f856d 100644
--- a/test/redirects.js
+++ b/test/redirects.js
@@ -86,6 +86,10 @@ test('follows redirect', async t => {
 	t.is((await got(`${http.url}/finite`)).body, 'reached');
 });
 
+test('does not follow redirect when disabled', async t => {
+	t.is((await got(`${http.url}/finite`, {followRedirect: false})).statusCode, 302);
+});
+
 test('relative redirect works', async t => {
 	t.is((await got(`${http.url}/relative`)).body, 'reached');
 });