Repository: node-nock/nock
Pull request #929 (2017-06-05 05:14:50)

Updates to unblock Node 8
We are currently blocked from full support of Node 8 due to nock.  This is my attempt to get nock working on Node 8.  If someone can review and give me pointers, I am willing to finish this up.

There is one browserify test failing on Node 7 and 8, but it seems to have been there before this change.


Patch:
diff --git a/.travis.yml b/.travis.yml
index 2cdf08b..71b633d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ node_js:
   - 4
   - 6
   - 7
+  - 8
 script: "npm run coverage && npm run integration"
 sudo: false
 after_success: "npm run coveralls"
diff --git a/lib/common.js b/lib/common.js
index 82b88e9..d302c34 100644
--- a/lib/common.js
+++ b/lib/common.js
@@ -2,6 +2,7 @@
 
 var _ = require('lodash');
 var debug = require('debug')('nock.common');
+var semver = require('semver')
 
 /**
  * Normalizes the request options so that it always has `host` property.
@@ -120,7 +121,8 @@ var overrideRequests = function(newRequest) {
           http: require('http'),
           https: require('https')
         }[moduleName],
-        overriddenRequest = module.request;
+        overriddenRequest = module.request,
+        overriddenGet = module.get;
 
     if(requestOverride[moduleName]) {
       throw new Error('Module\'s request already overridden for ' + moduleName + ' protocol.');
@@ -129,7 +131,8 @@ var overrideRequests = function(newRequest) {
     //  Store the properties of the overridden request so that it can be restored later on.
     requestOverride[moduleName] = {
       module: module,
-      request: overriddenRequest
+      request: overriddenRequest,
+      get: overriddenGet
     };
 
     module.request = function(options, callback) {
@@ -137,6 +140,14 @@ var overrideRequests = function(newRequest) {
       return newRequest(proto, overriddenRequest.bind(module), options, callback);
     };
 
+    if (semver.satisfies(process.version, '>=8')) {
+      module.get = function(options, callback) {
+        var req = newRequest(proto, overriddenRequest.bind(module), options, callback);
+        req.end();
+        return req;
+      }
+    }
+
     debug('- overridden request for', proto);
   });
 };
@@ -155,6 +166,7 @@ var restoreOverriddenRequests = function() {
     var override = requestOverride[proto];
     if(override) {
       override.module.request = override.request;
+      override.module.get = override.get;
       debug('- restored request for', proto);
     }
   });
diff --git a/lib/recorder.js b/lib/recorder.js
index 0dbecdf..d3ed439 100644
--- a/lib/recorder.js
+++ b/lib/recorder.js
@@ -8,6 +8,7 @@ var debug = require('debug')('nock.recorder');
 var _ = require('lodash');
 var Stream = require('stream');
 var URL = require('url');
+var semver = require('semver')
 
 var SEPARATOR = '\n<<<<<<-- cut here -->>>>>>\n';
 var recordingInProgress = false;
@@ -336,10 +337,25 @@ function record(rec_options) {
           }
           bodyChunks.push(data);
         }
-        oldWrite.call(req, data);
+        oldWrite.apply(req, arguments);
       }
     };
 
+    // in Node 8, res.end() does not call res.write() directly
+    if (semver.satisfies(process.version, '>=8')) {
+      var oldEnd = req.end;
+      req.end = function(data, encoding) {
+        if (data) {
+          debug(thisRecordingId, 'new', proto, 'body chunk');
+          if (! Buffer.isBuffer(data)) {
+            data = new Buffer(data, encoding);
+          }
+          bodyChunks.push(data);
+        }
+        oldEnd.apply(req, arguments);
+      };
+    }
+
     return req;
   });
 }
diff --git a/lib/request_overrider.js b/lib/request_overrider.js
index 59f8952..885aaf5 100644
--- a/lib/request_overrider.js
+++ b/lib/request_overrider.js
@@ -22,7 +22,7 @@ function getHeader(request, name) {
 
   var key = name.toLowerCase();
 
-  return request._headers[key];
+  return request.getHeader ? request.getHeader(key) : request._headers[key];
 }
 
 function setHeader(request, name, value) {
@@ -34,8 +34,12 @@ function setHeader(request, name, value) {
   request._headerNames = request._headerNames || {};
   request._removedHeader = request._removedHeader || {};
 
-  request._headers[key] = value;
-  request._headerNames[key] = name;
+  if (request.setHeader) {
+    request.setHeader(key, value);
+  } else {
+    request._headers[key] = value;
+    request._headerNames[key] = name;
+  }
 
   if (name == 'expect' && value == '100-continue') {
     timers.setImmediate(function() {
@@ -52,7 +56,8 @@ function setRequestHeaders(req, options, interceptor) {
   //  We mock request headers if these were specified.
   if (interceptor.reqheaders) {
     _.forOwn(interceptor.reqheaders, function(val, key) {
-      setHeader(req, key, val);
+      if (!_.isFunction(val))
+        setHeader(req, key, val);
     });
   }
 
@@ -268,7 +273,7 @@ function RequestOverrider(req, options, interceptors, remove, cb) {
     //  We again set request headers, now for our matched interceptor.
     setRequestHeaders(req, options, interceptor);
     interceptor.req = req;
-    req.headers = req._headers;
+    req.headers = req.getHeaders ? req.getHeaders() : req._headers;
 
     interceptor.scope.emit('request', req, interceptor);
 
diff --git a/package.json b/package.json
index 979b8ea..666eb3b 100644
--- a/package.json
+++ b/package.json
@@ -174,7 +174,8 @@
     "lodash": "~4.17.2",
     "mkdirp": "^0.5.0",
     "propagate": "0.4.0",
-    "qs": "^6.0.2"
+    "qs": "^6.0.2",
+    "semver": "^5.3.0"
   },
   "devDependencies": {
     "async": "^2.1.1",


Test patch:
diff --git a/tests/test_recorder.js b/tests/test_recorder.js
index 9376a27..a1c908f 100644
--- a/tests/test_recorder.js
+++ b/tests/test_recorder.js
@@ -280,8 +280,7 @@ test('records nonstandard ports', function(t) {
 
   //  Create test http server and perform the tests while it's up.
   var testServer = http.createServer(function(req, res) {
-    res.write(RESPONSE_BODY);
-    res.end();
+    res.end(RESPONSE_BODY);
   }).listen(8081, function(err) {
 
     t.equal(err, undefined);
@@ -731,8 +730,7 @@ test('works with clients listening for readable', {skip: process.env.AIRPLANE},
 
   //  Create test http server and perform the tests while it's up.
   var testServer = http.createServer(function(req, res) {
-    res.write(RESPONSE_BODY);
-    res.end();
+    res.end(RESPONSE_BODY);
   }).listen(8081, function(err) {
 
     // t.equal(err, undefined);