diff --git a/src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js b/src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js index 644cb36..0b40cde 100644 --- a/src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js +++ b/src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js @@ -121,8 +121,8 @@ var parsedArgs = ArgsUtil_1.parseArgs(process.argv); var 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 HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on + console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {' + server.address().address + '} port ' + server.address().port + '\]'); // Signal to the NodeServices base class that we're ready to accept invocations console.log('[Microsoft.AspNetCore.NodeServices:Listening]'); }); diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs index 69b12e4..1466db3 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs @@ -21,8 +21,8 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels /// internal class HttpNodeInstance : OutOfProcessNodeInstance { - private static readonly Regex PortMessageRegex = - new Regex(@"^\[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on port (\d+)\]$"); + private static readonly Regex EndpointMessageRegex = + new Regex(@"^\[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {(.*?)} port (\d+)\]$"); private static readonly JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings { @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels private readonly HttpClient _client; private bool _disposed; - private int _portNumber; + private string _endpoint; public HttpNodeInstance(NodeServicesOptions options, int port = 0) : base( @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels { var payloadJson = JsonConvert.SerializeObject(invocationInfo, jsonSerializerSettings); var payload = new StringContent(payloadJson, Encoding.UTF8, "application/json"); - var response = await _client.PostAsync("http://localhost:" + _portNumber, payload, cancellationToken); + var response = await _client.PostAsync(_endpoint, payload, cancellationToken); if (!response.IsSuccessStatusCode) { @@ -111,13 +111,19 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels protected override void OnOutputDataReceived(string outputData) { - // Watch for "port selected" messages, and when observed, store the port number + // Watch for "port selected" messages, and when observed, + // store the IP (IPv4/IPv6) and port number // so we can use it when making HTTP requests. The child process will always send // one of these messages before it sends a "ready for connections" message. - var match = _portNumber != 0 ? null : PortMessageRegex.Match(outputData); + var match = string.IsNullOrEmpty(_endpoint) ? EndpointMessageRegex.Match(outputData) : null; if (match != null && match.Success) { - _portNumber = int.Parse(match.Groups[1].Captures[0].Value); + var port = int.Parse(match.Groups[2].Captures[0].Value); + var resolvedIpAddress = match.Groups[1].Captures[0].Value; + + //IPv6 must be wrapped with [] brackets + resolvedIpAddress = resolvedIpAddress == "::1" ? $"[{resolvedIpAddress}]" : resolvedIpAddress; + _endpoint = $"http://{resolvedIpAddress}:{port}"; } else { diff --git a/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts b/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts index b9a8329..9e59fb5 100644 --- a/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts +++ b/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts @@ -70,8 +70,8 @@ const server = http.createServer((req, res) => { const parsedArgs = parseArgs(process.argv); 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 HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on + console.log('[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on {' + server.address().address + '} port ' + server.address().port + '\]'); // Signal to the NodeServices base class that we're ready to accept invocations console.log('[Microsoft.AspNetCore.NodeServices:Listening]');