From f7011e0472f8195924c9a3e6d705a8103bc97bde Mon Sep 17 00:00:00 2001
From: Dan Abramov <dan.abramov@gmail.com>
Date: Mon, 1 Aug 2016 15:38:05 +0100
Subject: [PATCH] Fix port detection lag on OS X with Firewall enabled (#319)

This fixes #302 by temporarily forking `detect-port`.
Hopefully this fix will be merged into the original project, and we can refer to it again.
---
 package.json                |  1 -
 scripts/eject.js            |  1 +
 scripts/start.js            |  2 +-
 scripts/utils/detectPort.js | 86 +++++++++++++++++++++++++++++++++++++
 4 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 scripts/utils/detectPort.js

diff --git a/package.json b/package.json
index 35243aed443..99dbed8207b 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,6 @@
     "chalk": "1.1.3",
     "cross-spawn": "4.0.0",
     "css-loader": "0.23.1",
-    "detect-port": "0.1.4",
     "eslint": "3.1.1",
     "eslint-loader": "1.4.1",
     "eslint-plugin-flowtype": "2.4.0",
diff --git a/scripts/eject.js b/scripts/eject.js
index 0319b00b34f..2772aa2a3b3 100644
--- a/scripts/eject.js
+++ b/scripts/eject.js
@@ -40,6 +40,7 @@ prompt(
     path.join('scripts', 'build.js'),
     path.join('scripts', 'start.js'),
     path.join('scripts', 'utils', 'chrome.applescript'),
+    path.join('scripts', 'utils', 'detectPort.js'),
     path.join('scripts', 'utils', 'prompt.js')
   ];
 
diff --git a/scripts/start.js b/scripts/start.js
index c93754df3b0..3c8d8e46825 100644
--- a/scripts/start.js
+++ b/scripts/start.js
@@ -15,7 +15,7 @@ var webpack = require('webpack');
 var WebpackDevServer = require('webpack-dev-server');
 var execSync = require('child_process').execSync;
 var opn = require('opn');
-var detect = require('detect-port');
+var detect = require('./utils/detectPort');
 var prompt = require('./utils/prompt');
 var config = require('../config/webpack.config.dev');
 
diff --git a/scripts/utils/detectPort.js b/scripts/utils/detectPort.js
new file mode 100644
index 00000000000..759a59f8d04
--- /dev/null
+++ b/scripts/utils/detectPort.js
@@ -0,0 +1,86 @@
+/* ================================================================
+ * detect-port by xdf(xudafeng[at]126.com)
+ *
+ * first created at : Tue Mar 17 2015 00:16:10 GMT+0800 (CST)
+ *
+ * ================================================================
+ * Copyright xdf
+ *
+ * Licensed under the MIT License
+ * You may not use this file except in compliance with the License.
+ *
+ * ================================================================ */
+
+// We are forking this temporarily to resolve
+// https://github.com/facebookincubator/create-react-app/issues/302.
+
+// We can replace this fork with `detect-port` package when this is merged:
+// https://github.com/xudafeng/detect-port/pull/4.
+
+'use strict';
+
+var net = require('net');
+
+var inject = function(port) {
+  var options = global.__detect ? global.__detect.options : {};
+
+  if (options.verbose) {
+    console.log('port %d was occupied', port);
+  }
+};
+
+function detect(port, fn) {
+
+  var _detect = function(port) {
+    return new Promise(function(resolve, reject) {
+      var socket = new net.Socket();
+      socket.once('error', function() {
+        socket.removeAllListeners('connect');
+        socket.removeAllListeners('error');
+        socket.end();
+        socket.destroy();
+        socket.unref();
+        var server = new net.Server();
+        server.on('error', function() {
+          inject(port);
+          port++;
+          resolve(_detect(port));
+        });
+
+        server.listen(port, function() {
+          server.once('close', function() {
+            resolve(port);
+          });
+          server.close();
+        });
+      });
+      socket.once('connect', function() {
+        inject(port);
+        port++;
+        resolve(_detect(port));
+        socket.removeAllListeners('connect');
+        socket.removeAllListeners('error');
+        socket.end();
+        socket.destroy();
+        socket.unref();
+      });
+      socket.connect({
+        port: port
+      });
+    });
+  }
+
+  var _detect_with_cb = function(_fn) {
+    _detect(port)
+      .then(function(result) {
+        _fn(null, result);
+      })
+      .catch(function(e) {
+        _fn(e);
+      });
+  };
+
+  return fn ? _detect_with_cb(fn) : _detect(port);
+}
+
+module.exports = detect;