Add support for port 0 in HttpSys (#13841)
This commit is contained in:
parent
71c5c66b21
commit
96f1c92caa
|
|
@ -56,34 +56,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int BasePort = 5001;
|
|
||||||
private const int MaxPort = 8000;
|
|
||||||
private static int NextPort = BasePort;
|
|
||||||
|
|
||||||
// GetNextPort doesn't check for HttpSys urlacls.
|
|
||||||
public static int GetNextHttpSysPort(string scheme)
|
|
||||||
{
|
|
||||||
while (NextPort < MaxPort)
|
|
||||||
{
|
|
||||||
var port = NextPort++;
|
|
||||||
|
|
||||||
using (var server = new HttpListener())
|
|
||||||
{
|
|
||||||
server.Prefixes.Add($"{scheme}://localhost:{port}/");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
server.Start();
|
|
||||||
server.Stop();
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
catch (HttpListenerException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NextPort = BasePort;
|
|
||||||
throw new Exception("Failed to locate a free port.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
|
namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
|
||||||
{
|
{
|
||||||
public static class TestUriHelper
|
public static class TestUriHelper
|
||||||
|
|
@ -34,7 +36,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common
|
||||||
}
|
}
|
||||||
else if (serverType == ServerType.HttpSys)
|
else if (serverType == ServerType.HttpSys)
|
||||||
{
|
{
|
||||||
return new UriBuilder(scheme, "localhost", TestPortHelper.GetNextHttpSysPort(scheme)).Uri;
|
Debug.Assert(scheme == "http", "Https not supported");
|
||||||
|
return new UriBuilder(scheme, "localhost", 0).Uri;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,18 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.AspNetCore.HttpSys.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.HttpSys
|
namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
|
|
@ -74,6 +76,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
}
|
}
|
||||||
|
|
||||||
var hostingUrlsPresent = _serverAddresses.Addresses.Count > 0;
|
var hostingUrlsPresent = _serverAddresses.Addresses.Count > 0;
|
||||||
|
var serverAddressCopy = _serverAddresses.Addresses.ToList();
|
||||||
|
_serverAddresses.Addresses.Clear();
|
||||||
|
|
||||||
if (_serverAddresses.PreferHostingUrls && hostingUrlsPresent)
|
if (_serverAddresses.PreferHostingUrls && hostingUrlsPresent)
|
||||||
{
|
{
|
||||||
|
|
@ -85,10 +89,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Listener.Options.UrlPrefixes.Clear();
|
Listener.Options.UrlPrefixes.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var value in _serverAddresses.Addresses)
|
UpdateUrlPrefixes(serverAddressCopy);
|
||||||
{
|
|
||||||
Listener.Options.UrlPrefixes.Add(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_options.UrlPrefixes.Count > 0)
|
else if (_options.UrlPrefixes.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -100,23 +101,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
_serverAddresses.Addresses.Clear();
|
_serverAddresses.Addresses.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var prefix in _options.UrlPrefixes)
|
|
||||||
{
|
|
||||||
_serverAddresses.Addresses.Add(prefix.FullPrefix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (hostingUrlsPresent)
|
else if (hostingUrlsPresent)
|
||||||
{
|
{
|
||||||
foreach (var value in _serverAddresses.Addresses)
|
UpdateUrlPrefixes(serverAddressCopy);
|
||||||
{
|
|
||||||
Listener.Options.UrlPrefixes.Add(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogHelper.LogDebug(_logger, $"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default.");
|
LogHelper.LogDebug(_logger, $"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default.");
|
||||||
|
|
||||||
_serverAddresses.Addresses.Add(Constants.DefaultServerAddress);
|
|
||||||
Listener.Options.UrlPrefixes.Add(Constants.DefaultServerAddress);
|
Listener.Options.UrlPrefixes.Add(Constants.DefaultServerAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,6 +122,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
Listener.Start();
|
Listener.Start();
|
||||||
|
|
||||||
|
// Update server addresses after we start listening as port 0
|
||||||
|
// needs to be selected at the point of binding.
|
||||||
|
foreach (var prefix in _options.UrlPrefixes)
|
||||||
|
{
|
||||||
|
_serverAddresses.Addresses.Add(prefix.FullPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
ActivateRequestProcessingLimits();
|
ActivateRequestProcessingLimits();
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
@ -142,6 +142,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateUrlPrefixes(IList<string> serverAddressCopy)
|
||||||
|
{
|
||||||
|
foreach (var value in serverAddressCopy)
|
||||||
|
{
|
||||||
|
Listener.Options.UrlPrefixes.Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The message pump.
|
// The message pump.
|
||||||
// When we start listening for the next request on one thread, we may need to be sure that the
|
// When we start listening for the next request on one thread, we may need to be sure that the
|
||||||
// completion continues on another thread as to not block the current request processing.
|
// completion continues on another thread as to not block the current request processing.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -73,7 +73,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
LogHelper.LogInfo(_logger, "Listening on prefix: " + uriPrefix);
|
LogHelper.LogInfo(_logger, "Listening on prefix: " + uriPrefix);
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
var statusCode = HttpApi.HttpAddUrlToUrlGroup(Id, uriPrefix, (ulong)contextId, 0);
|
var statusCode = HttpApi.HttpAddUrlToUrlGroup(Id, uriPrefix, (ulong)contextId, 0);
|
||||||
|
|
||||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
|
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.HttpSys
|
namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
|
|
@ -15,6 +20,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
private UrlGroup _urlGroup;
|
private UrlGroup _urlGroup;
|
||||||
private int _nextId = 1;
|
private int _nextId = 1;
|
||||||
|
|
||||||
|
// Valid port range of 5000 - 48000.
|
||||||
|
private const int BasePort = 5000;
|
||||||
|
private const int MaxPortIndex = 43000;
|
||||||
|
private const int MaxRetries = 1000;
|
||||||
|
private static int NextPortIndex;
|
||||||
|
|
||||||
internal UrlPrefixCollection()
|
internal UrlPrefixCollection()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -138,10 +149,55 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
_urlGroup = urlGroup;
|
_urlGroup = urlGroup;
|
||||||
// go through the uri list and register for each one of them
|
// go through the uri list and register for each one of them
|
||||||
foreach (var pair in _prefixes)
|
// Call ToList to avoid modification when enumerating.
|
||||||
|
foreach (var pair in _prefixes.ToList())
|
||||||
{
|
{
|
||||||
// We'll get this index back on each request and use it to look up the prefix to calculate PathBase.
|
var urlPrefix = pair.Value;
|
||||||
_urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key);
|
if (urlPrefix.PortValue == 0)
|
||||||
|
{
|
||||||
|
if (urlPrefix.IsHttps)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Cannot bind to port 0 with https.");
|
||||||
|
}
|
||||||
|
|
||||||
|
FindHttpPortUnsynchronized(pair.Key, urlPrefix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We'll get this index back on each request and use it to look up the prefix to calculate PathBase.
|
||||||
|
_urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FindHttpPortUnsynchronized(int key, UrlPrefix urlPrefix)
|
||||||
|
{
|
||||||
|
for (var index = 0; index < MaxRetries; index++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Bit of complicated math to always try 3000 ports, starting from NextPortIndex + 5000,
|
||||||
|
// circling back around if we go above 8000 back to 5000, and so on.
|
||||||
|
var port = ((index + NextPortIndex) % MaxPortIndex) + BasePort;
|
||||||
|
|
||||||
|
Debug.Assert(port >= 5000 || port < 8000);
|
||||||
|
|
||||||
|
var newPrefix = UrlPrefix.Create(urlPrefix.Scheme, urlPrefix.Host, port, urlPrefix.Path);
|
||||||
|
_urlGroup.RegisterPrefix(newPrefix.FullPrefix, key);
|
||||||
|
_prefixes[key] = newPrefix;
|
||||||
|
|
||||||
|
NextPortIndex += index + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (HttpSysException ex)
|
||||||
|
{
|
||||||
|
if ((ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_ACCESS_DENIED
|
||||||
|
&& ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SHARING_VIOLATION
|
||||||
|
&& ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS) || index == MaxRetries - 1)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -159,4 +215,4 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
%~dp0..\..\..\startvs.cmd %~dp0HttpSysServer.sln
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -114,7 +114,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
server.StartAsync(new DummyApplication(), CancellationToken.None).Wait();
|
server.StartAsync(new DummyApplication(), CancellationToken.None).Wait();
|
||||||
|
|
||||||
Assert.Equal(Constants.DefaultServerAddress, server.Features.Get<IServerAddressesFeature>().Addresses.Single());
|
// Trailing slash is added when put in UrlPrefix.
|
||||||
|
Assert.StartsWith(Constants.DefaultServerAddress, server.Features.Get<IServerAddressesFeature>().Addresses.Single());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
|
@ -21,11 +22,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
{
|
{
|
||||||
// When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free
|
// When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free
|
||||||
// ports during dynamic port allocation.
|
// ports during dynamic port allocation.
|
||||||
private const int BasePort = 5001;
|
|
||||||
private const int MaxPort = 8000;
|
|
||||||
private const int BaseHttpsPort = 44300;
|
private const int BaseHttpsPort = 44300;
|
||||||
private const int MaxHttpsPort = 44399;
|
private const int MaxHttpsPort = 44399;
|
||||||
private static int NextPort = BasePort;
|
|
||||||
private static int NextHttpsPort = BaseHttpsPort;
|
private static int NextHttpsPort = BaseHttpsPort;
|
||||||
private static object PortLock = new object();
|
private static object PortLock = new object();
|
||||||
internal static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15);
|
internal static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15);
|
||||||
|
|
@ -84,39 +82,26 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
internal static IWebHost CreateDynamicHost(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app)
|
internal static IWebHost CreateDynamicHost(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app)
|
||||||
{
|
{
|
||||||
lock (PortLock)
|
var prefix = UrlPrefix.Create("http", "localhost", "0", basePath);
|
||||||
{
|
|
||||||
while (NextPort < MaxPort)
|
var builder = new WebHostBuilder()
|
||||||
|
.UseHttpSys(options =>
|
||||||
{
|
{
|
||||||
var port = NextPort++;
|
options.UrlPrefixes.Add(prefix);
|
||||||
var prefix = UrlPrefix.Create("http", "localhost", port, basePath);
|
configureOptions(options);
|
||||||
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
|
})
|
||||||
baseAddress = prefix.ToString();
|
.Configure(appBuilder => appBuilder.Run(app));
|
||||||
|
|
||||||
var builder = new WebHostBuilder()
|
var host = builder.Build();
|
||||||
.UseHttpSys(options =>
|
|
||||||
{
|
|
||||||
options.UrlPrefixes.Add(prefix);
|
|
||||||
configureOptions(options);
|
|
||||||
})
|
|
||||||
.Configure(appBuilder => appBuilder.Run(app));
|
|
||||||
|
|
||||||
var host = builder.Build();
|
host.Start();
|
||||||
|
|
||||||
|
var options = host.Services.GetRequiredService<IOptions<HttpSysOptions>>();
|
||||||
|
prefix = options.Value.UrlPrefixes.First(); // Has new port
|
||||||
|
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
|
||||||
|
baseAddress = prefix.ToString();
|
||||||
|
|
||||||
try
|
return host;
|
||||||
{
|
|
||||||
host.Start();
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
catch (HttpSysException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
NextPort = BasePort;
|
|
||||||
}
|
|
||||||
throw new Exception("Failed to locate a free port.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static MessagePump CreatePump()
|
internal static MessagePump CreatePump()
|
||||||
|
|
@ -124,31 +109,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
internal static IServer CreateDynamicHttpServer(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app)
|
internal static IServer CreateDynamicHttpServer(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app)
|
||||||
{
|
{
|
||||||
lock (PortLock)
|
var prefix = UrlPrefix.Create("http", "localhost", "0", basePath);
|
||||||
{
|
|
||||||
while (NextPort < MaxPort)
|
|
||||||
{
|
|
||||||
|
|
||||||
var port = NextPort++;
|
var server = CreatePump();
|
||||||
var prefix = UrlPrefix.Create("http", "localhost", port, basePath);
|
server.Features.Get<IServerAddressesFeature>().Addresses.Add(prefix.ToString());
|
||||||
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
|
configureOptions(server.Listener.Options);
|
||||||
baseAddress = prefix.ToString();
|
server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait();
|
||||||
|
|
||||||
var server = CreatePump();
|
prefix = server.Listener.Options.UrlPrefixes.First(); // Has new port
|
||||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress);
|
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
|
||||||
configureOptions(server.Listener.Options);
|
baseAddress = prefix.ToString();
|
||||||
try
|
|
||||||
{
|
return server;
|
||||||
server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait();
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
catch (HttpSysException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NextPort = BasePort;
|
|
||||||
}
|
|
||||||
throw new Exception("Failed to locate a free port.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IServer CreateDynamicHttpsServer(out string baseAddress, RequestDelegate app)
|
internal static IServer CreateDynamicHttpsServer(out string baseAddress, RequestDelegate app)
|
||||||
|
|
@ -184,6 +156,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
throw new Exception("Failed to locate a free port.");
|
throw new Exception("Failed to locate a free port.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static Task WithTimeout(this Task task) => task.TimeoutAfter(DefaultTimeout);
|
internal static Task WithTimeout(this Task task) => task.TimeoutAfter(DefaultTimeout);
|
||||||
|
|
||||||
internal static Task<T> WithTimeout<T>(this Task<T> task) => task.TimeoutAfter(DefaultTimeout);
|
internal static Task<T> WithTimeout<T>(this Task<T> task) => task.TimeoutAfter(DefaultTimeout);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
|
||||||
internal static class ErrorCodes
|
internal static class ErrorCodes
|
||||||
{
|
{
|
||||||
internal const uint ERROR_SUCCESS = 0;
|
internal const uint ERROR_SUCCESS = 0;
|
||||||
|
internal const uint ERROR_ACCESS_DENIED = 5;
|
||||||
|
internal const uint ERROR_SHARING_VIOLATION = 32;
|
||||||
internal const uint ERROR_HANDLE_EOF = 38;
|
internal const uint ERROR_HANDLE_EOF = 38;
|
||||||
internal const uint ERROR_NOT_SUPPORTED = 50;
|
internal const uint ERROR_NOT_SUPPORTED = 50;
|
||||||
internal const uint ERROR_INVALID_PARAMETER = 87;
|
internal const uint ERROR_INVALID_PARAMETER = 87;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue