mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 10:08:57 +00:00
Migrate entrypoint-http.js to TypeScript. Source is now HttpNodeInstanceEntryPoint.ts.
This commit is contained in:
@@ -1,47 +1,103 @@
|
|||||||
|
(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var installedModules = {};
|
||||||
|
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ if(installedModules[moduleId])
|
||||||
|
/******/ return installedModules[moduleId].exports;
|
||||||
|
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
/******/ exports: {},
|
||||||
|
/******/ id: moduleId,
|
||||||
|
/******/ loaded: false
|
||||||
|
/******/ };
|
||||||
|
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||||
|
|
||||||
|
/******/ // Flag the module as loaded
|
||||||
|
/******/ module.loaded = true;
|
||||||
|
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
|
||||||
|
|
||||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||||
|
/******/ __webpack_require__.m = modules;
|
||||||
|
|
||||||
|
/******/ // expose the module cache
|
||||||
|
/******/ __webpack_require__.c = installedModules;
|
||||||
|
|
||||||
|
/******/ // __webpack_public_path__
|
||||||
|
/******/ __webpack_require__.p = "";
|
||||||
|
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ return __webpack_require__(0);
|
||||||
|
/******/ })
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ ([
|
||||||
|
/* 0 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
module.exports = __webpack_require__(1);
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 1 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
// but simplifies things for the consumer of this module.
|
// but simplifies things for the consumer of this module.
|
||||||
var http = require('http');
|
var http = __webpack_require__(2);
|
||||||
var path = require('path');
|
var path = __webpack_require__(3);
|
||||||
var parsedArgs = parseArgs(process.argv);
|
var ArgsUtil_1 = __webpack_require__(4);
|
||||||
var requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide'
|
var AutoQuit_1 = __webpack_require__(5);
|
||||||
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
|
// reference to Node's runtime 'require' function.
|
||||||
|
var dynamicRequire = eval('require');
|
||||||
|
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
|
||||||
if (parsedArgs.watch) {
|
if (parsedArgs.watch) {
|
||||||
autoQuitOnFileChange(process.cwd(), parsedArgs.watch.split(','));
|
AutoQuit_1.autoQuitOnFileChange(process.cwd(), parsedArgs.watch.split(','));
|
||||||
}
|
}
|
||||||
|
|
||||||
var server = http.createServer(function (req, res) {
|
var server = http.createServer(function (req, res) {
|
||||||
readRequestBodyAsJson(req, function (bodyJson) {
|
readRequestBodyAsJson(req, function (bodyJson) {
|
||||||
var resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName);
|
var resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName);
|
||||||
var invokedModule = require(resolvedPath);
|
var invokedModule = dynamicRequire(resolvedPath);
|
||||||
var func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule;
|
var func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule;
|
||||||
if (!func) {
|
if (!func) {
|
||||||
throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"');
|
throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasSentResult = false;
|
var hasSentResult = false;
|
||||||
var callback = function (errorValue, successValue) {
|
var callback = function (errorValue, successValue) {
|
||||||
if (!hasSentResult) {
|
if (!hasSentResult) {
|
||||||
hasSentResult = true;
|
hasSentResult = true;
|
||||||
if (errorValue) {
|
if (errorValue) {
|
||||||
res.statusCode = 500;
|
res.statusCode = 500;
|
||||||
|
|
||||||
if (errorValue.stack) {
|
if (errorValue.stack) {
|
||||||
res.end(errorValue.stack);
|
res.end(errorValue.stack);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
res.end(errorValue.toString());
|
res.end(errorValue.toString());
|
||||||
}
|
}
|
||||||
} else if (typeof successValue !== 'string') {
|
}
|
||||||
|
else if (typeof successValue !== 'string') {
|
||||||
// Arbitrary object/number/etc - JSON-serialize it
|
// Arbitrary object/number/etc - JSON-serialize it
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.end(JSON.stringify(successValue));
|
res.end(JSON.stringify(successValue));
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// String - can bypass JSON-serialization altogether
|
// String - can bypass JSON-serialization altogether
|
||||||
res.setHeader('Content-Type', 'text/plain');
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
res.end(successValue);
|
res.end(successValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Support streamed responses
|
// Support streamed responses
|
||||||
Object.defineProperty(callback, 'stream', {
|
Object.defineProperty(callback, 'stream', {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
@@ -50,27 +106,24 @@ var server = http.createServer(function(req, res) {
|
|||||||
hasSentResult = true;
|
hasSentResult = true;
|
||||||
res.setHeader('Content-Type', 'application/octet-stream');
|
res.setHeader('Content-Type', 'application/octet-stream');
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
func.apply(null, [callback].concat(bodyJson.args));
|
func.apply(null, [callback].concat(bodyJson.args));
|
||||||
} catch (synchronousException) {
|
}
|
||||||
|
catch (synchronousException) {
|
||||||
callback(synchronousException, null);
|
callback(synchronousException, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
var requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide'
|
||||||
server.listen(requestedPortOrZero, 'localhost', function () {
|
server.listen(requestedPortOrZero, 'localhost', function () {
|
||||||
// Signal to HttpNodeHost which port it should make its HTTP connections on
|
// Signal to HttpNodeHost which port it should make its HTTP connections on
|
||||||
console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on port ' + server.address().port + '\]');
|
console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on port ' + server.address().port + '\]');
|
||||||
|
|
||||||
// Signal to the NodeServices base class that we're ready to accept invocations
|
// Signal to the NodeServices base class that we're ready to accept invocations
|
||||||
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
|
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
|
||||||
});
|
});
|
||||||
|
|
||||||
function readRequestBodyAsJson(request, callback) {
|
function readRequestBodyAsJson(request, callback) {
|
||||||
var requestBodyAsString = '';
|
var requestBodyAsString = '';
|
||||||
request
|
request
|
||||||
@@ -78,20 +131,24 @@ function readRequestBodyAsJson(request, callback) {
|
|||||||
.on('end', function () { callback(JSON.parse(requestBodyAsString)); });
|
.on('end', function () { callback(JSON.parse(requestBodyAsString)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoQuitOnFileChange(rootDir, extensions) {
|
|
||||||
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
|
||||||
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
|
||||||
var fs = require('fs');
|
|
||||||
var path = require('path');
|
|
||||||
fs.watch(rootDir, { persistent: false, recursive: true }, function(event, filename) {
|
|
||||||
var ext = path.extname(filename);
|
|
||||||
if (extensions.indexOf(ext) >= 0) {
|
|
||||||
console.log('Restarting due to file change: ' + filename);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 2 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("http");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 3 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("path");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 4 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
function parseArgs(args) {
|
function parseArgs(args) {
|
||||||
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
||||||
// dependencies (such as an args-parsing library) to this file.
|
// dependencies (such as an args-parsing library) to this file.
|
||||||
@@ -102,11 +159,43 @@ function parseArgs(args) {
|
|||||||
var argName = arg.substring(2);
|
var argName = arg.substring(2);
|
||||||
result[argName] = undefined;
|
result[argName] = undefined;
|
||||||
currentKey = argName;
|
currentKey = argName;
|
||||||
} else if (currentKey) {
|
}
|
||||||
|
else if (currentKey) {
|
||||||
result[currentKey] = arg;
|
result[currentKey] = arg;
|
||||||
currentKey = null;
|
currentKey = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
exports.parseArgs = parseArgs;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 5 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var fs = __webpack_require__(6);
|
||||||
|
var path = __webpack_require__(3);
|
||||||
|
function autoQuitOnFileChange(rootDir, extensions) {
|
||||||
|
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
||||||
|
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
||||||
|
fs.watch(rootDir, { persistent: false, recursive: true }, function (event, filename) {
|
||||||
|
var ext = path.extname(filename);
|
||||||
|
if (extensions.indexOf(ext) >= 0) {
|
||||||
|
console.log('Restarting due to file change: ' + filename);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.autoQuitOnFileChange = autoQuitOnFileChange;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 6 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("fs");
|
||||||
|
|
||||||
|
/***/ }
|
||||||
|
/******/ ])));
|
||||||
@@ -44,27 +44,89 @@
|
|||||||
/* 0 */
|
/* 0 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
module.exports = __webpack_require__(1);
|
module.exports = __webpack_require__(7);
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 1 */
|
/* 1 */,
|
||||||
|
/* 2 */,
|
||||||
|
/* 3 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("path");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 4 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
function parseArgs(args) {
|
||||||
|
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
||||||
|
// dependencies (such as an args-parsing library) to this file.
|
||||||
|
var result = {};
|
||||||
|
var currentKey = null;
|
||||||
|
args.forEach(function (arg) {
|
||||||
|
if (arg.indexOf('--') === 0) {
|
||||||
|
var argName = arg.substring(2);
|
||||||
|
result[argName] = undefined;
|
||||||
|
currentKey = argName;
|
||||||
|
}
|
||||||
|
else if (currentKey) {
|
||||||
|
result[currentKey] = arg;
|
||||||
|
currentKey = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
exports.parseArgs = parseArgs;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 5 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var fs = __webpack_require__(6);
|
||||||
|
var path = __webpack_require__(3);
|
||||||
|
function autoQuitOnFileChange(rootDir, extensions) {
|
||||||
|
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
||||||
|
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
||||||
|
fs.watch(rootDir, { persistent: false, recursive: true }, function (event, filename) {
|
||||||
|
var ext = path.extname(filename);
|
||||||
|
if (extensions.indexOf(ext) >= 0) {
|
||||||
|
console.log('Restarting due to file change: ' + filename);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.autoQuitOnFileChange = autoQuitOnFileChange;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 6 */
|
||||||
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
|
module.exports = require("fs");
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 7 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
// but simplifies things for the consumer of this module.
|
// but simplifies things for the consumer of this module.
|
||||||
var fs = __webpack_require__(2);
|
var net = __webpack_require__(8);
|
||||||
var net = __webpack_require__(3);
|
var path = __webpack_require__(3);
|
||||||
var path = __webpack_require__(4);
|
var readline = __webpack_require__(9);
|
||||||
var readline = __webpack_require__(5);
|
var ArgsUtil_1 = __webpack_require__(4);
|
||||||
var virtualConnectionServer = __webpack_require__(6);
|
var AutoQuit_1 = __webpack_require__(5);
|
||||||
|
var virtualConnectionServer = __webpack_require__(10);
|
||||||
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
// reference to Node's runtime 'require' function.
|
// reference to Node's runtime 'require' function.
|
||||||
var dynamicRequire = eval('require');
|
var dynamicRequire = eval('require');
|
||||||
var parsedArgs = parseArgs(process.argv);
|
var parsedArgs = ArgsUtil_1.parseArgs(process.argv);
|
||||||
if (parsedArgs.watch) {
|
if (parsedArgs.watch) {
|
||||||
autoQuitOnFileChange(process.cwd(), parsedArgs.watch.split(','));
|
AutoQuit_1.autoQuitOnFileChange(process.cwd(), parsedArgs.watch.split(','));
|
||||||
}
|
}
|
||||||
// Signal to the .NET side when we're ready to accept invocations
|
// Signal to the .NET side when we're ready to accept invocations
|
||||||
var server = net.createServer().on('listening', function () {
|
var server = net.createServer().on('listening', function () {
|
||||||
@@ -116,68 +178,27 @@
|
|||||||
var useWindowsNamedPipes = /^win/.test(process.platform);
|
var useWindowsNamedPipes = /^win/.test(process.platform);
|
||||||
var listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.pipename;
|
var listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.pipename;
|
||||||
server.listen(listenAddress);
|
server.listen(listenAddress);
|
||||||
function autoQuitOnFileChange(rootDir, extensions) {
|
|
||||||
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
|
||||||
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
|
||||||
fs.watch(rootDir, { persistent: false, recursive: true }, function (event, filename) {
|
|
||||||
var ext = path.extname(filename);
|
|
||||||
if (extensions.indexOf(ext) >= 0) {
|
|
||||||
console.log('Restarting due to file change: ' + filename);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function parseArgs(args) {
|
|
||||||
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
|
||||||
// dependencies (such as an args-parsing library) to this file.
|
|
||||||
var result = {};
|
|
||||||
var currentKey = null;
|
|
||||||
args.forEach(function (arg) {
|
|
||||||
if (arg.indexOf('--') === 0) {
|
|
||||||
var argName = arg.substring(2);
|
|
||||||
result[argName] = undefined;
|
|
||||||
currentKey = argName;
|
|
||||||
}
|
|
||||||
else if (currentKey) {
|
|
||||||
result[currentKey] = arg;
|
|
||||||
currentKey = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 2 */
|
/* 8 */
|
||||||
/***/ function(module, exports) {
|
|
||||||
|
|
||||||
module.exports = require("fs");
|
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 3 */
|
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("net");
|
module.exports = require("net");
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 4 */
|
/* 9 */
|
||||||
/***/ function(module, exports) {
|
|
||||||
|
|
||||||
module.exports = require("path");
|
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 5 */
|
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("readline");
|
module.exports = require("readline");
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 6 */
|
/* 10 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
var events_1 = __webpack_require__(7);
|
var events_1 = __webpack_require__(11);
|
||||||
var VirtualConnection_1 = __webpack_require__(8);
|
var VirtualConnection_1 = __webpack_require__(12);
|
||||||
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
|
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
|
||||||
// and both will reject longer frames.
|
// and both will reject longer frames.
|
||||||
var MaxFrameBodyLength = 16 * 1024;
|
var MaxFrameBodyLength = 16 * 1024;
|
||||||
@@ -358,13 +379,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 7 */
|
/* 11 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("events");
|
module.exports = require("events");
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 8 */
|
/* 12 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -373,7 +394,7 @@
|
|||||||
function __() { this.constructor = d; }
|
function __() { this.constructor = d; }
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
};
|
};
|
||||||
var stream_1 = __webpack_require__(9);
|
var stream_1 = __webpack_require__(13);
|
||||||
/**
|
/**
|
||||||
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
|
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
|
||||||
*/
|
*/
|
||||||
@@ -414,7 +435,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 9 */
|
/* 13 */
|
||||||
/***/ function(module, exports) {
|
/***/ function(module, exports) {
|
||||||
|
|
||||||
module.exports = require("stream");
|
module.exports = require("stream");
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
|
// but simplifies things for the consumer of this module.
|
||||||
|
import * as http from 'http';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { parseArgs } from './Util/ArgsUtil';
|
||||||
|
import { autoQuitOnFileChange } from './Util/AutoQuit';
|
||||||
|
|
||||||
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
|
// reference to Node's runtime 'require' function.
|
||||||
|
const dynamicRequire: (name: string) => any = eval('require');
|
||||||
|
|
||||||
|
const parsedArgs = parseArgs(process.argv);
|
||||||
|
if (parsedArgs.watch) {
|
||||||
|
autoQuitOnFileChange(process.cwd(), parsedArgs.watch.split(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
readRequestBodyAsJson(req, bodyJson => {
|
||||||
|
const resolvedPath = path.resolve(process.cwd(), bodyJson.moduleName);
|
||||||
|
const invokedModule = dynamicRequire(resolvedPath);
|
||||||
|
const func = bodyJson.exportedFunctionName ? invokedModule[bodyJson.exportedFunctionName] : invokedModule;
|
||||||
|
if (!func) {
|
||||||
|
throw new Error('The module "' + resolvedPath + '" has no export named "' + bodyJson.exportedFunctionName + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasSentResult = false;
|
||||||
|
const callback = (errorValue, successValue) => {
|
||||||
|
if (!hasSentResult) {
|
||||||
|
hasSentResult = true;
|
||||||
|
if (errorValue) {
|
||||||
|
res.statusCode = 500;
|
||||||
|
|
||||||
|
if (errorValue.stack) {
|
||||||
|
res.end(errorValue.stack);
|
||||||
|
} else {
|
||||||
|
res.end(errorValue.toString());
|
||||||
|
}
|
||||||
|
} else if (typeof successValue !== 'string') {
|
||||||
|
// Arbitrary object/number/etc - JSON-serialize it
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.end(JSON.stringify(successValue));
|
||||||
|
} else {
|
||||||
|
// String - can bypass JSON-serialization altogether
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.end(successValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Support streamed responses
|
||||||
|
Object.defineProperty(callback, 'stream', {
|
||||||
|
enumerable: true,
|
||||||
|
get: function() {
|
||||||
|
if (!hasSentResult) {
|
||||||
|
hasSentResult = true;
|
||||||
|
res.setHeader('Content-Type', 'application/octet-stream');
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
func.apply(null, [callback].concat(bodyJson.args));
|
||||||
|
} catch (synchronousException) {
|
||||||
|
callback(synchronousException, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const requestedPortOrZero = parsedArgs.port || 0; // 0 means 'let the OS decide'
|
||||||
|
server.listen(requestedPortOrZero, 'localhost', function () {
|
||||||
|
// Signal to HttpNodeHost which port it should make its HTTP connections on
|
||||||
|
console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on port ' + server.address().port + '\]');
|
||||||
|
|
||||||
|
// Signal to the NodeServices base class that we're ready to accept invocations
|
||||||
|
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
|
||||||
|
});
|
||||||
|
|
||||||
|
function readRequestBodyAsJson(request, callback) {
|
||||||
|
let requestBodyAsString = '';
|
||||||
|
request
|
||||||
|
.on('data', chunk => { requestBodyAsString += chunk; })
|
||||||
|
.on('end', () => { callback(JSON.parse(requestBodyAsString)); });
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
|
||||||
// but simplifies things for the consumer of this module.
|
// but simplifies things for the consumer of this module.
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as readline from 'readline';
|
import * as readline from 'readline';
|
||||||
import { Duplex } from 'stream';
|
import { Duplex } from 'stream';
|
||||||
|
import { parseArgs } from './Util/ArgsUtil';
|
||||||
|
import { autoQuitOnFileChange } from './Util/AutoQuit';
|
||||||
import * as virtualConnectionServer from './VirtualConnections/VirtualConnectionServer';
|
import * as virtualConnectionServer from './VirtualConnections/VirtualConnectionServer';
|
||||||
|
|
||||||
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
|
||||||
@@ -71,37 +72,6 @@ const useWindowsNamedPipes = /^win/.test(process.platform);
|
|||||||
const listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.pipename;
|
const listenAddress = (useWindowsNamedPipes ? '\\\\.\\pipe\\' : '/tmp/') + parsedArgs.pipename;
|
||||||
server.listen(listenAddress);
|
server.listen(listenAddress);
|
||||||
|
|
||||||
function autoQuitOnFileChange(rootDir: string, extensions: string[]) {
|
|
||||||
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
|
||||||
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
|
||||||
fs.watch(rootDir, { persistent: false, recursive: true } as any, (event, filename) => {
|
|
||||||
var ext = path.extname(filename);
|
|
||||||
if (extensions.indexOf(ext) >= 0) {
|
|
||||||
console.log('Restarting due to file change: ' + filename);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseArgs(args: string[]): any {
|
|
||||||
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
|
||||||
// dependencies (such as an args-parsing library) to this file.
|
|
||||||
const result = {};
|
|
||||||
let currentKey = null;
|
|
||||||
args.forEach(arg => {
|
|
||||||
if (arg.indexOf('--') === 0) {
|
|
||||||
const argName = arg.substring(2);
|
|
||||||
result[argName] = undefined;
|
|
||||||
currentKey = argName;
|
|
||||||
} else if (currentKey) {
|
|
||||||
result[currentKey] = arg;
|
|
||||||
currentKey = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RpcInvocation {
|
interface RpcInvocation {
|
||||||
moduleName: string;
|
moduleName: string;
|
||||||
exportedFunctionName: string;
|
exportedFunctionName: string;
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
export function parseArgs(args: string[]): any {
|
||||||
|
// Very simplistic parsing which is sufficient for the cases needed. We don't want to bring in any external
|
||||||
|
// dependencies (such as an args-parsing library) to this file.
|
||||||
|
const result = {};
|
||||||
|
let currentKey = null;
|
||||||
|
args.forEach(arg => {
|
||||||
|
if (arg.indexOf('--') === 0) {
|
||||||
|
const argName = arg.substring(2);
|
||||||
|
result[argName] = undefined;
|
||||||
|
currentKey = argName;
|
||||||
|
} else if (currentKey) {
|
||||||
|
result[currentKey] = arg;
|
||||||
|
currentKey = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export function autoQuitOnFileChange(rootDir: string, extensions: string[]) {
|
||||||
|
// Note: This will only work on Windows/OS X, because the 'recursive' option isn't supported on Linux.
|
||||||
|
// Consider using a different watch mechanism (though ideally without forcing further NPM dependencies).
|
||||||
|
fs.watch(rootDir, { persistent: false, recursive: true } as any, (event, filename) => {
|
||||||
|
var ext = path.extname(filename);
|
||||||
|
if (extensions.indexOf(ext) >= 0) {
|
||||||
|
console.log('Restarting due to file change: ' + filename);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
|
'entrypoint-http': ['./TypeScript/HttpNodeInstanceEntryPoint'],
|
||||||
'entrypoint-socket': ['./TypeScript/SocketNodeInstanceEntryPoint'],
|
'entrypoint-socket': ['./TypeScript/SocketNodeInstanceEntryPoint'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
|
|||||||
Reference in New Issue
Block a user