From f8057d24fcd8edcb9cf09214d7cf460ad77e7ae2 Mon Sep 17 00:00:00 2001
From: Vsevolod Strukchinsky <floatdrop@gmail.com>
Date: Sun, 5 Apr 2015 22:13:47 +0500
Subject: [PATCH] Add json option

---
 index.js          | 12 ++++++++++++
 readme.md         |  9 +++++++++
 test/test-json.js | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)
 create mode 100644 test/test-json.js

diff --git a/index.js b/index.js
index 75c53ee..8ffceeb 100644
--- a/index.js
+++ b/index.js
@@ -40,11 +40,13 @@ function got(url, opts, cb) {
 
 	var encoding = opts.encoding;
 	var body = opts.body;
+	var json = opts.json;
 	var proxy;
 	var redirectCount = 0;
 
 	delete opts.encoding;
 	delete opts.body;
+	delete opts.json;
 
 	if (body) {
 		opts.method = opts.method || 'POST';
@@ -61,6 +63,10 @@ function got(url, opts, cb) {
 		};
 	}
 
+	if (proxy && json) {
+		throw new GotError('got can not be used as stream when options.json is used');
+	}
+
 	function get(url, opts, cb) {
 		var parsedUrl = urlLib.parse(prependHttp(url));
 		var fn = parsedUrl.protocol === 'https:' ? https : http;
@@ -116,6 +122,12 @@ function got(url, opts, cb) {
 			read(res, encoding, function (err, data) {
 				if (err) {
 					err = new GotError('Reading ' + url + ' response failed', err);
+				} else if (json) {
+					try {
+						data = JSON.parse(data);
+					} catch (e) {
+						err = new GotError('Parsing ' + url + ' response failed', err);
+					}
 				}
 
 				cb(err, data, response);
diff --git a/readme.md b/readme.md
index 8d2b778..6fb0963 100644
--- a/readme.md
+++ b/readme.md
@@ -69,6 +69,15 @@ _This option and stream mode are mutually exclusive._
 
 Body, that will be sent with `POST` request. If present in `options` and `options.method` is not set - `options.method` will be set to `POST`.
 
+##### options.json
+
+Type: `Boolean`  
+Default: `false`
+
+_This option and stream mode are mutually exclusive._
+
+If enabled, response body will be parsed with `JSON.parse`.
+
 ##### options.timeout
 
 Type: `number`
diff --git a/test/test-json.js b/test/test-json.js
new file mode 100644
index 0000000..f508ac8
--- /dev/null
+++ b/test/test-json.js
@@ -0,0 +1,48 @@
+'use strict';
+var tape = require('tape');
+var got = require('../');
+var server = require('./server.js');
+var s = server.createServer();
+
+s.on('/', function (req, res) {
+	res.end('{"data":"dog"}');
+});
+
+s.on('/invalid', function (req, res) {
+	res.end('/');
+});
+
+
+tape('setup', function (t) {
+	s.listen(s.port, function () {
+		t.end();
+	});
+});
+
+tape('json option can not be used in stream mode', function (t) {
+	t.throws(function () {
+		got(s.url, {json: true});
+	}, 'got can not be used as stream when options.json is used');
+	t.end();
+});
+
+tape('json option should parse response', function (t) {
+	got(s.url, {json: true}, function (err, json) {
+		t.error(err);
+		t.deepEqual(json, {data: 'dog'});
+		t.end();
+	});
+});
+
+tape('json option wrap parsing errors', function (t) {
+	got(s.url + '/invalid', {json: true}, function (err) {
+		t.ok(err);
+		t.equal(err.message, 'Parsing ' + s.url + '/invalid response failed');
+		t.end();
+	});
+});
+
+tape('cleanup', function (t) {
+	s.close();
+	t.end();
+});