From 235ac59551daf3ac46860814699eade72e89cf23 Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 27 Jul 2016 10:29:15 -0700 Subject: [PATCH] API cleaup, organization --- samples/HelloWorld/Program.cs | 4 +- samples/HotAddSample/Startup.cs | 2 - samples/SelfHostServer/Startup.cs | 1 - .../AuthenticationHandler.cs | 4 +- .../FeatureContext.cs | 4 +- .../Internal/WebListenerOptionsSetup.cs | 1 - .../MessagePump.cs | 36 +-- .../Properties/AssemblyInfo.cs | 2 + .../WebHostBuilderWebListenerExtensions.cs | 3 - .../WebListenerOptions.cs | 9 +- .../AuthenticationManager.cs | 2 +- .../NativeInterop/UnsafeNativeMethods.cs | 29 +- .../RequestProcessing/ClientCertLoader.cs | 12 +- .../RequestProcessing/Request.cs | 275 ++++-------------- .../RequestProcessing/RequestContext.cs | 128 +++----- .../RequestProcessing/RequestStream.cs | 31 +- .../RequestProcessing/Response.cs | 116 ++++---- .../RequestProcessing/ResponseStream.cs | 42 +-- .../TimeoutManager.cs | 80 ++--- src/Microsoft.Net.Http.Server/WebListener.cs | 127 ++++---- .../project.json | 4 + .../AuthenticationTests.cs | 36 +-- .../HttpsTests.cs | 10 +- .../OpaqueUpgradeTests.cs | 8 +- .../RequestBodyTests.cs | 26 +- .../RequestHeaderTests.cs | 6 +- .../RequestTests.cs | 10 +- .../ResponseBodyTests.cs | 38 +-- .../ResponseCachingTests.cs | 86 +++--- .../ResponseHeaderTests.cs | 34 +-- .../ResponseSendFileTests.cs | 26 +- .../ResponseTests.cs | 12 +- .../ServerTests.cs | 24 +- .../WebSocketTests.cs | 6 +- 34 files changed, 495 insertions(+), 739 deletions(-) diff --git a/samples/HelloWorld/Program.cs b/samples/HelloWorld/Program.cs index 0285c349fa..7e74bf87d0 100644 --- a/samples/HelloWorld/Program.cs +++ b/samples/HelloWorld/Program.cs @@ -18,13 +18,13 @@ namespace HelloWorld { using (WebListener listener = new WebListener()) { - listener.UrlPrefixes.Add(UrlPrefix.Create("http://localhost:8080")); + listener.UrlPrefixes.Add("http://localhost:8080"); listener.Start(); Console.WriteLine("Running..."); while (true) { - RequestContext context = await listener.GetContextAsync(); + RequestContext context = await listener.AcceptAsync(); Console.WriteLine("Accepted"); // Context: diff --git a/samples/HotAddSample/Startup.cs b/samples/HotAddSample/Startup.cs index d3b7753f80..1fa57b5606 100644 --- a/samples/HotAddSample/Startup.cs +++ b/samples/HotAddSample/Startup.cs @@ -2,8 +2,6 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; -using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Server; diff --git a/samples/SelfHostServer/Startup.cs b/samples/SelfHostServer/Startup.cs index 3e3d72be83..81875a0af2 100644 --- a/samples/SelfHostServer/Startup.cs +++ b/samples/SelfHostServer/Startup.cs @@ -5,7 +5,6 @@ using System.Threading; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Server.WebListener; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; diff --git a/src/Microsoft.AspNetCore.Server.WebListener/AuthenticationHandler.cs b/src/Microsoft.AspNetCore.Server.WebListener/AuthenticationHandler.cs index b1f9aec312..bd1df634e9 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/AuthenticationHandler.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/AuthenticationHandler.cs @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Server.WebListener internal AuthenticationHandler(RequestContext requestContext) { _requestContext = requestContext; - _authSchemes = requestContext.AuthenticationChallenges; + _authSchemes = requestContext.Response.AuthenticationChallenges; _customChallenges = AuthenticationSchemes.None; } @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.Server.WebListener } } // A challenge was issued, it overrides any pre-set auth types. - _requestContext.AuthenticationChallenges = _customChallenges; + _requestContext.Response.AuthenticationChallenges = _customChallenges; return Task.FromResult(0); } diff --git a/src/Microsoft.AspNetCore.Server.WebListener/FeatureContext.cs b/src/Microsoft.AspNetCore.Server.WebListener/FeatureContext.cs index ec906fdf37..61109f123f 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/FeatureContext.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/FeatureContext.cs @@ -323,7 +323,7 @@ namespace Microsoft.AspNetCore.Server.WebListener internal ITlsConnectionFeature GetTlsConnectionFeature() { - return Request.IsSecureConnection ? this : null; + return Request.IsHttps ? this : null; } byte[] ITlsTokenBindingFeature.GetProvidedTokenBindingId() @@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Server.WebListener internal ITlsTokenBindingFeature GetTlsTokenBindingFeature() { - return Request.IsSecureConnection ? this : null; + return Request.IsHttps ? this : null; } void IHttpBufferingFeature.DisableRequestBuffering() diff --git a/src/Microsoft.AspNetCore.Server.WebListener/Internal/WebListenerOptionsSetup.cs b/src/Microsoft.AspNetCore.Server.WebListener/Internal/WebListenerOptionsSetup.cs index 5e27bbf8c2..eeba2f8b91 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/Internal/WebListenerOptionsSetup.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/Internal/WebListenerOptionsSetup.cs @@ -15,7 +15,6 @@ // See the Apache 2 License for the specific language governing // permissions and limitations under the License. -using System; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/Microsoft.AspNetCore.Server.WebListener/MessagePump.cs b/src/Microsoft.AspNetCore.Server.WebListener/MessagePump.cs index 554a090c8d..4ba6599e2a 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/MessagePump.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/MessagePump.cs @@ -29,10 +29,8 @@ using Microsoft.Net.Http.Server; namespace Microsoft.AspNetCore.Server.WebListener { - public class MessagePump : IServer + internal class MessagePump : IServer { - private static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount; - private readonly Microsoft.Net.Http.Server.WebListener _listener; private readonly ILogger _logger; @@ -48,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.WebListener private readonly ServerAddressesFeature _serverAddresses; - public MessagePump(IOptions options, ILoggerFactory loggerFactory) + internal MessagePump(IOptions options, ILoggerFactory loggerFactory) { if (options == null) { @@ -66,32 +64,17 @@ namespace Microsoft.AspNetCore.Server.WebListener Features.Set(_serverAddresses); _processRequest = new Action(ProcessRequestAsync); - _maxAccepts = DefaultMaxAccepts; + _maxAccepts = options.Value?.MaxAccepts ?? WebListenerOptions.DefaultMaxAccepts; + EnableResponseCaching = options.Value?.EnableResponseCaching ?? true; _shutdownSignal = new ManualResetEvent(false); } - public Microsoft.Net.Http.Server.WebListener Listener + internal Microsoft.Net.Http.Server.WebListener Listener { get { return _listener; } } - internal int MaxAccepts - { - get - { - return _maxAccepts; - } - set - { - _maxAccepts = value; - if (_listener.IsListening) - { - ActivateRequestProcessingLimits(); - } - } - } - - internal bool EnableResponseCaching { get; set; } = true; + internal bool EnableResponseCaching { get; set; } public IFeatureCollection Features { get; } @@ -123,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.WebListener private void ActivateRequestProcessingLimits() { - for (int i = _acceptorCounts; i < MaxAccepts; i++) + for (int i = _acceptorCounts; i < _maxAccepts; i++) { ProcessRequestsWorker(); } @@ -136,13 +119,13 @@ namespace Microsoft.AspNetCore.Server.WebListener private async void ProcessRequestsWorker() { int workerIndex = Interlocked.Increment(ref _acceptorCounts); - while (!_stopping && workerIndex <= MaxAccepts) + while (!_stopping && workerIndex <= _maxAccepts) { // Receive a request RequestContext requestContext; try { - requestContext = await _listener.GetContextAsync().SupressContext(); + requestContext = await _listener.AcceptAsync().SupressContext(); } catch (Exception exception) { @@ -237,7 +220,6 @@ namespace Microsoft.AspNetCore.Server.WebListener } } - public void Dispose() { _stopping = true; diff --git a/src/Microsoft.AspNetCore.Server.WebListener/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Server.WebListener/Properties/AssemblyInfo.cs index 79eeb571ef..17fae786fd 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/Properties/AssemblyInfo.cs @@ -3,9 +3,11 @@ using System.Reflection; using System.Resources; +using System.Runtime.CompilerServices; [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: NeutralResourcesLanguage("en-us")] [assembly: AssemblyCompany("Microsoft Corporation.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft ASP.NET Core")] +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Server.WebListener.FunctionalTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.WebListener/WebHostBuilderWebListenerExtensions.cs b/src/Microsoft.AspNetCore.Server.WebListener/WebHostBuilderWebListenerExtensions.cs index 51c658b9f0..f314cb1c4a 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/WebHostBuilderWebListenerExtensions.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/WebHostBuilderWebListenerExtensions.cs @@ -16,9 +16,6 @@ // permissions and limitations under the License. using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Server.WebListener; using Microsoft.AspNetCore.Server.WebListener.Internal; diff --git a/src/Microsoft.AspNetCore.Server.WebListener/WebListenerOptions.cs b/src/Microsoft.AspNetCore.Server.WebListener/WebListenerOptions.cs index 814314e9a2..9613f6d468 100644 --- a/src/Microsoft.AspNetCore.Server.WebListener/WebListenerOptions.cs +++ b/src/Microsoft.AspNetCore.Server.WebListener/WebListenerOptions.cs @@ -16,14 +16,17 @@ // permissions and limitations under the License. using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace Microsoft.AspNetCore.Server.WebListener { public class WebListenerOptions { + internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount; + public Microsoft.Net.Http.Server.WebListener Listener { get; set; } = new Microsoft.Net.Http.Server.WebListener(); + + public int MaxAccepts { get; set; } = DefaultMaxAccepts; + + public bool EnableResponseCaching { get; set; } = true; } } diff --git a/src/Microsoft.Net.Http.Server/AuthenticationManager.cs b/src/Microsoft.Net.Http.Server/AuthenticationManager.cs index 877e8077ed..32d7ee2e69 100644 --- a/src/Microsoft.Net.Http.Server/AuthenticationManager.cs +++ b/src/Microsoft.Net.Http.Server/AuthenticationManager.cs @@ -144,7 +144,7 @@ namespace Microsoft.Net.Http.Server internal void SetAuthenticationChallenge(RequestContext context) { - IList challenges = GenerateChallenges(context.AuthenticationChallenges); + IList challenges = GenerateChallenges(context.Response.AuthenticationChallenges); if (challenges.Count > 0) { diff --git a/src/Microsoft.Net.Http.Server/NativeInterop/UnsafeNativeMethods.cs b/src/Microsoft.Net.Http.Server/NativeInterop/UnsafeNativeMethods.cs index b5a4162058..b9e2c71f72 100644 --- a/src/Microsoft.Net.Http.Server/NativeInterop/UnsafeNativeMethods.cs +++ b/src/Microsoft.Net.Http.Server/NativeInterop/UnsafeNativeMethods.cs @@ -1105,7 +1105,8 @@ namespace Microsoft.Net.Http.Server } } - private static unsafe string GetVerb(HTTP_REQUEST* request, long fixup) + // This requires the HTTP_REQUEST to still be pinned in its original location. + internal static unsafe string GetVerb(HTTP_REQUEST* request) { string verb = null; @@ -1115,31 +1116,7 @@ namespace Microsoft.Net.Http.Server } else if (request->Verb == HTTP_VERB.HttpVerbUnknown && request->pUnknownVerb != null) { - verb = HeaderEncoding.GetString(request->pUnknownVerb + fixup, request->UnknownVerbLength); - } - - return verb; - } - - internal static unsafe string GetVerb(byte[] memoryBlob, int requestOffset, IntPtr originalAddress) - { - fixed (byte* pMemoryBlob = memoryBlob) - { - return GetVerb((HTTP_REQUEST*)(pMemoryBlob + requestOffset), pMemoryBlob - (byte*)originalAddress); - } - } - - internal static HTTP_VERB GetKnownVerb(byte[] memoryBlob, int requestOffset, IntPtr originalAddress) - { - // Return value. - HTTP_VERB verb = HTTP_VERB.HttpVerbUnknown; - fixed (byte* pMemoryBlob = memoryBlob) - { - HTTP_REQUEST* request = (HTTP_REQUEST*)(pMemoryBlob + requestOffset); - if ((int)request->Verb > (int)HTTP_VERB.HttpVerbUnparsed && (int)request->Verb < (int)HTTP_VERB.HttpVerbMaximum) - { - verb = request->Verb; - } + verb = HeaderEncoding.GetString(request->pUnknownVerb, request->UnknownVerbLength); } return verb; diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs index 62197abf1f..63df5bdc89 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs @@ -67,10 +67,12 @@ namespace Microsoft.Net.Http.Server if (cancellationToken.CanBeCanceled) { - _cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext); + _cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken); } } + internal SafeHandle RequestQueueHandle => _requestContext.Server.RequestQueue.Handle; + internal X509Certificate2 ClientCert { get @@ -184,8 +186,8 @@ namespace Microsoft.Net.Http.Server uint statusCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate( - RequestContext.RequestQueueHandle, - RequestContext.Request.ConnectionId, + RequestQueueHandle, + RequestContext.Request.UConnectionId, (uint)UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE, RequestBlob, size, @@ -263,8 +265,8 @@ namespace Microsoft.Net.Http.Server uint bytesReceived = 0; errorCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveClientCertificate( - requestContext.RequestQueueHandle, - requestContext.Request.ConnectionId, + requestContext.Server.RequestQueue.Handle, + requestContext.Request.UConnectionId, (uint)UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE, asyncResult._memoryBlob, asyncResult._size, diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs index 72bc826284..659ec35310 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs @@ -22,48 +22,25 @@ //------------------------------------------------------------------------------ using System; -using System.Collections; -using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Runtime.InteropServices; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; -using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; namespace Microsoft.Net.Http.Server { public sealed class Request { - private RequestContext _requestContext; private NativeRequestContext _nativeRequestContext; - private ulong _requestId; - private ulong _connectionId; - private ulong _contextId; - - private SslStatus _sslStatus; - - private string _httpMethod; - private Version _httpVersion; - - // private Uri _requestUri; - private string _rawUrl; - private string _cookedUrlHost; - private string _cookedUrlPath; - private string _cookedUrlQuery; - private string _pathBase; - private string _path; - private X509Certificate2 _clientCert; private byte[] _providedTokenBindingId; private byte[] _referredTokenBindingId; - private HeaderCollection _headers; private BoundaryType _contentBoundaryType; private long? _contentLength; private Stream _nativeStream; @@ -71,116 +48,90 @@ namespace Microsoft.Net.Http.Server private SocketAddress _localEndPoint; private SocketAddress _remoteEndPoint; - private ClaimsPrincipal _user; - private bool _isDisposed = false; - internal unsafe Request(RequestContext httpContext, NativeRequestContext memoryBlob) + internal unsafe Request(RequestContext requestContext, NativeRequestContext memoryBlob) { // TODO: Verbose log - _requestContext = httpContext; + RequestContext = requestContext; _nativeRequestContext = memoryBlob; _contentBoundaryType = BoundaryType.None; // Set up some of these now to avoid refcounting on memory blob later. - _requestId = memoryBlob.RequestBlob->RequestId; - _connectionId = memoryBlob.RequestBlob->ConnectionId; - _contextId = memoryBlob.RequestBlob->UrlContext; - _sslStatus = memoryBlob.RequestBlob->pSslInfo == null ? SslStatus.Insecure : + RequestId = memoryBlob.RequestBlob->RequestId; + UConnectionId = memoryBlob.RequestBlob->ConnectionId; + SslStatus = memoryBlob.RequestBlob->pSslInfo == null ? SslStatus.Insecure : memoryBlob.RequestBlob->pSslInfo->SslClientCertNegotiated == 0 ? SslStatus.NoClientCert : SslStatus.ClientCert; if (memoryBlob.RequestBlob->pRawUrl != null && memoryBlob.RequestBlob->RawUrlLength > 0) { - _rawUrl = Marshal.PtrToStringAnsi((IntPtr)memoryBlob.RequestBlob->pRawUrl, memoryBlob.RequestBlob->RawUrlLength); + RawUrl = Marshal.PtrToStringAnsi((IntPtr)memoryBlob.RequestBlob->pRawUrl, memoryBlob.RequestBlob->RawUrlLength); } UnsafeNclNativeMethods.HttpApi.HTTP_COOKED_URL cookedUrl = memoryBlob.RequestBlob->CookedUrl; if (cookedUrl.pHost != null && cookedUrl.HostLength > 0) { - _cookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2); + // TODO: Unused + // _cookedUrlHost = Marshal.PtrToStringUni((IntPtr)cookedUrl.pHost, cookedUrl.HostLength / 2); } + var cookedUrlPath = string.Empty; if (cookedUrl.pAbsPath != null && cookedUrl.AbsPathLength > 0) { - _cookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2); + cookedUrlPath = Marshal.PtrToStringUni((IntPtr)cookedUrl.pAbsPath, cookedUrl.AbsPathLength / 2); } + QueryString = string.Empty; if (cookedUrl.pQueryString != null && cookedUrl.QueryStringLength > 0) { - _cookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2); + QueryString = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2); } - UrlPrefix prefix = httpContext.Server.UrlPrefixes.GetPrefix((int)_contextId); - string originalPath = RequestPath; + var prefix = requestContext.Server.UrlPrefixes.GetPrefix((int)memoryBlob.RequestBlob->UrlContext); + var originalPath = RequestUriBuilder.GetRequestPath(RawUrl, cookedUrlPath, RequestContext.Logger); // These paths are both unescaped already. if (originalPath.Length == prefix.Path.Length - 1) { // They matched exactly except for the trailing slash. - _pathBase = originalPath; - _path = string.Empty; + PathBase = originalPath; + Path = string.Empty; } else { // url: /base/path, prefix: /base/, base: /base, path: /path // url: /, prefix: /, base: , path: / - _pathBase = originalPath.Substring(0, prefix.Path.Length - 1); - _path = originalPath.Substring(prefix.Path.Length - 1); + PathBase = originalPath.Substring(0, prefix.Path.Length - 1); + Path = originalPath.Substring(prefix.Path.Length - 1); } int major = memoryBlob.RequestBlob->Version.MajorVersion; int minor = memoryBlob.RequestBlob->Version.MinorVersion; if (major == 1 && minor == 1) { - _httpVersion = Constants.V1_1; + ProtocolVersion = Constants.V1_1; } else if (major == 1 && minor == 0) { - _httpVersion = Constants.V1_0; + ProtocolVersion = Constants.V1_0; } else { - _httpVersion = new Version(major, minor); + ProtocolVersion = new Version(major, minor); } - _httpMethod = UnsafeNclNativeMethods.HttpApi.GetVerb(RequestBuffer, BufferAlignment, OriginalBlobAddress); - _headers = new HeaderCollection(new RequestHeaders(_nativeRequestContext)); + KnownMethod = memoryBlob.RequestBlob->Verb; + Method = UnsafeNclNativeMethods.HttpApi.GetVerb(memoryBlob.RequestBlob); + Headers = new HeaderCollection(new RequestHeaders(_nativeRequestContext)); var requestV2 = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)memoryBlob.RequestBlob; - _user = AuthenticationManager.GetUser(requestV2->pRequestInfo, requestV2->RequestInfoCount); + User = AuthenticationManager.GetUser(requestV2->pRequestInfo, requestV2->RequestInfoCount); GetTlsTokenBindingInfo(); + // Finished directly accessing the HTTP_REQUEST structure. + _nativeRequestContext.ReleasePins(); // TODO: Verbose log parameters } - internal SslStatus SslStatus - { - get - { - return _sslStatus; - } - } - - public ulong ConnectionId - { - get - { - return _connectionId; - } - } - - internal ulong ContextId - { - get { return _contextId; } - } - - internal RequestContext RequestContext - { - get - { - return _requestContext; - } - } - internal byte[] RequestBuffer { get @@ -208,26 +159,19 @@ namespace Microsoft.Net.Http.Server } } - // With the leading ?, if any - public string QueryString - { - get - { - return _cookedUrlQuery ?? string.Empty; - } - set - { - _cookedUrlQuery = value; - } - } + internal ulong UConnectionId { get; } - internal ulong RequestId - { - get - { - return _requestId; - } - } + // No ulongs in public APIs... + public long ConnectionId => (long)UConnectionId; + + internal ulong RequestId { get; } + + private SslStatus SslStatus { get; } + + private RequestContext RequestContext { get; } + + // With the leading ?, if any + public string QueryString { get; } public long? ContentLength { @@ -261,20 +205,13 @@ namespace Microsoft.Net.Http.Server } } - public HeaderCollection Headers - { - get { return _headers; } - } + public HeaderCollection Headers { get; } - public string Method - { - get { return _httpMethod; } - } + private UnsafeNclNativeMethods.HttpApi.HTTP_VERB KnownMethod { get; } - public bool IsHeadMethod - { - get { return string.Equals(_httpMethod, "HEAD", StringComparison.OrdinalIgnoreCase); } - } + public bool IsHeadMethod => KnownMethod == UnsafeNclNativeMethods.HttpApi.HTTP_VERB.HttpVerbHEAD; + + public string Method { get; } public Stream Body { @@ -288,39 +225,15 @@ namespace Microsoft.Net.Http.Server } } - public string PathBase - { - get { return _pathBase; } - } + public string PathBase { get; } - public string Path - { - get { return _path; } - } + public string Path { get; } - public bool IsSecureConnection - { - get - { - return _sslStatus != SslStatus.Insecure; - } - } + public bool IsHttps => SslStatus != SslStatus.Insecure; - public string RawUrl - { - get - { - return _rawUrl; - } - } + public string RawUrl { get; } - public Version ProtocolVersion - { - get - { - return _httpVersion; - } - } + public Version ProtocolVersion { get; } public bool HasEntityBody { @@ -358,65 +271,24 @@ namespace Microsoft.Net.Http.Server } } - public IPAddress RemoteIpAddress - { - get { return RemoteEndPoint.GetIPAddress(); } - } + // TODO: Lazy cache? + public IPAddress RemoteIpAddress => RemoteEndPoint.GetIPAddress(); - public IPAddress LocalIpAddress - { - get { return LocalEndPoint.GetIPAddress(); } - } + public IPAddress LocalIpAddress => LocalEndPoint.GetIPAddress(); - public int RemotePort - { - get { return RemoteEndPoint.GetPort(); } - } + public int RemotePort => RemoteEndPoint.GetPort(); - public int LocalPort - { - get { return LocalEndPoint.GetPort(); } - } + public int LocalPort => LocalEndPoint.GetPort(); - public string Scheme - { - get { return IsSecureConnection ? Constants.HttpsScheme : Constants.HttpScheme; } - } + public string Scheme => IsHttps ? Constants.HttpsScheme : Constants.HttpScheme; - internal string RequestPath - { - get - { - return RequestUriBuilder.GetRequestPath(_rawUrl, _cookedUrlPath, RequestContext.Logger); - } - } + // HTTP.Sys allows you to upgrade anything to opaque unless content-length > 0 or chunked are specified. + // TODO: >= Win8 check https://github.com/aspnet/WebListener/issues/215 + internal bool IsUpgradable => !HasEntityBody; - internal bool IsUpgradable - { - get - { - // HTTP.Sys allows you to upgrade anything to opaque unless content-length > 0 or chunked are specified. - return !HasEntityBody; - } - } + public string ContentType => Headers[HttpKnownHeaderNames.ContentType]; - public string ContentType - { - get - { - return Headers[HttpKnownHeaderNames.ContentType]; - } - } - - internal ClaimsPrincipal User - { - get { return _user; } - } - - internal UnsafeNclNativeMethods.HttpApi.HTTP_VERB GetKnownMethod() - { - return UnsafeNclNativeMethods.HttpApi.GetKnownVerb(RequestBuffer, BufferAlignment, OriginalBlobAddress); - } + internal ClaimsPrincipal User { get; } // Populates the client certificate. The result may be null if there is no client cert. // TODO: Does it make sense for this to be invoked multiple times (e.g. renegotiate)? Client and server code appear to @@ -435,7 +307,7 @@ namespace Microsoft.Net.Http.Server } cancellationToken.ThrowIfCancellationRequested(); - ClientCertLoader certLoader = new ClientCertLoader(RequestContext, cancellationToken); + var certLoader = new ClientCertLoader(RequestContext, cancellationToken); try { await certLoader.LoadClientCertificateAsync().SupressContext(); @@ -489,40 +361,19 @@ namespace Microsoft.Net.Http.Server } } - // Use this to save the blob from dispose if this object was never used (never given to a user) and is about to be - // disposed. - internal void DetachBlob(NativeRequestContext memoryBlob) - { - if (memoryBlob != null && (object)memoryBlob == (object)_nativeRequestContext) - { - _nativeRequestContext = null; - } - } - - // Finalizes ownership of the memory blob. DetachBlob can't be called after this. - internal void ReleasePins() - { - _nativeRequestContext.ReleasePins(); - } - // should only be called from RequestContext internal void Dispose() { // TODO: Verbose log _isDisposed = true; - NativeRequestContext memoryBlob = _nativeRequestContext; - if (memoryBlob != null) - { - memoryBlob.Dispose(); - _nativeRequestContext = null; - } + _nativeRequestContext.Dispose(); if (_nativeStream != null) { _nativeStream.Dispose(); } } - internal void CheckDisposed() + private void CheckDisposed() { if (_isDisposed) { diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs index c0fede1e33..99c5221a82 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs @@ -23,9 +23,7 @@ using System; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.InteropServices; using System.Security.Authentication.ExtendedProtection; using System.Security.Claims; using System.Threading; @@ -36,47 +34,31 @@ namespace Microsoft.Net.Http.Server { public sealed class RequestContext : IDisposable { - internal static readonly Action AbortDelegate = Abort; + private static readonly Action AbortDelegate = Abort; - private WebListener _server; - private Request _request; - private Response _response; private NativeRequestContext _memoryBlob; - private bool _disposed; private CancellationTokenSource _requestAbortSource; private CancellationToken? _disconnectToken; + private bool _disposed; internal RequestContext(WebListener server, NativeRequestContext memoryBlob) { // TODO: Verbose log - _server = server; + Server = server; _memoryBlob = memoryBlob; - _request = new Request(this, _memoryBlob); - _response = new Response(this); - _request.ReleasePins(); - AuthenticationChallenges = server.AuthenticationManager.AuthenticationSchemes & ~AuthenticationSchemes.AllowAnonymous; + Request = new Request(this, _memoryBlob); + Response = new Response(this); } - public Request Request - { - get - { - return _request; - } - } + internal WebListener Server { get; } - public Response Response - { - get - { - return _response; - } - } + internal ILogger Logger => Server.Logger; - public ClaimsPrincipal User - { - get { return _request.User; } - } + public Request Request { get; } + + public Response Response { get; } + + public ClaimsPrincipal User => Request.User; public CancellationToken DisconnectToken { @@ -86,7 +68,7 @@ namespace Microsoft.Net.Http.Server // We need to be able to dispose of the registrations each request to prevent leaks. if (!_disconnectToken.HasValue) { - var connectionDisconnectToken = _server.DisconnectListener.GetTokenForConnection(Request.ConnectionId); + var connectionDisconnectToken = Server.DisconnectListener.GetTokenForConnection(Request.UConnectionId); if (connectionDisconnectToken.CanBeCanceled) { @@ -102,64 +84,29 @@ namespace Microsoft.Net.Http.Server } } - internal WebListener Server - { - get - { - return _server; - } - } - - internal ILogger Logger - { - get { return Server.Logger; } - } - - internal SafeHandle RequestQueueHandle - { - get - { - return _server.RequestQueue.Handle; - } - } - - internal ulong RequestId - { - get - { - return Request.RequestId; - } - } - public unsafe Guid TraceIdentifier { get { // This is the base GUID used by HTTP.SYS for generating the activity ID. // HTTP.SYS overwrites the first 8 bytes of the base GUID with RequestId to generate ETW activity ID. - var guid = new Guid(0xffcb4c93, 0xa57f, 0x453c, 0xb6, 0x3f, 0x84, 0x71, 0xc, 0x79, 0x67, 0xbb); *((ulong*)&guid) = Request.RequestId; return guid; } } - /// - /// The authentication challengest that will be added to the response if the status code is 401. - /// This must be a subset of the AuthenticationSchemes enabled on the server. - /// - public AuthenticationSchemes AuthenticationChallenges { get; set; } - - public bool IsUpgradableRequest - { - get { return _request.IsUpgradable; } - } + public bool IsUpgradableRequest => Request.IsUpgradable; public Task UpgradeAsync() { - if (!IsUpgradableRequest || _response.HasStarted) + if (!IsUpgradableRequest) { - throw new InvalidOperationException("This request cannot be upgraded. It is incompatible, or the response has already started."); + throw new InvalidOperationException("This request cannot be upgraded, it is incompatible."); + } + if (Response.HasStarted) + { + throw new InvalidOperationException("This request cannot be upgraded, the response has already started."); } // Set the status code and reason phrase @@ -176,19 +123,22 @@ namespace Microsoft.Net.Http.Server // TODO: Public when needed internal bool TryGetChannelBinding(ref ChannelBinding value) { - if (!Request.IsSecureConnection) + if (!Request.IsHttps) { LogHelper.LogDebug(Logger, "TryGetChannelBinding", "Channel binding requires HTTPS."); return false; } - value = ClientCertLoader.GetChannelBindingFromTls(Server.RequestQueue, Request.ConnectionId, Logger); + value = ClientCertLoader.GetChannelBindingFromTls(Server.RequestQueue, Request.UConnectionId, Logger); Debug.Assert(value != null, "GetChannelBindingFromTls returned null even though OS supposedly supports Extended Protection"); LogHelper.LogInfo(Logger, "Channel binding retrieved."); return value != null; } + /// + /// Flushes and completes the response. + /// public void Dispose() { if (_disposed) @@ -204,14 +154,17 @@ namespace Microsoft.Net.Http.Server { _requestAbortSource.Dispose(); } - _response.Dispose(); + Response.Dispose(); } finally { - _request.Dispose(); + Request.Dispose(); } } + /// + /// Forcibly terminate and dispose the request, closing the connection if necessary. + /// public void Abort() { // May be called from Dispose() code path, don't check _disposed. @@ -229,8 +182,8 @@ namespace Microsoft.Net.Http.Server } _requestAbortSource.Dispose(); } - ForceCancelRequest(RequestQueueHandle, _request.RequestId); - _request.Dispose(); + ForceCancelRequest(); + Request.Dispose(); } private static void Abort(object state) @@ -239,30 +192,25 @@ namespace Microsoft.Net.Http.Server context.Abort(); } - // This is only called while processing incoming requests. We don't have to worry about canceling - // any response writes. - [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = - "It is safe to ignore the return value on a cancel operation because the connection is being closed")] - internal static void CancelRequest(SafeHandle requestQueueHandle, ulong requestId) + internal CancellationTokenRegistration RegisterForCancellation(CancellationToken cancellationToken) { - UnsafeNclNativeMethods.HttpApi.HttpCancelHttpRequest(requestQueueHandle, requestId, - IntPtr.Zero); + return cancellationToken.Register(AbortDelegate, this); } // The request is being aborted, but large writes may be in progress. Cancel them. - internal void ForceCancelRequest(SafeHandle requestQueueHandle, ulong requestId) + internal void ForceCancelRequest() { try { - uint statusCode = UnsafeNclNativeMethods.HttpApi.HttpCancelHttpRequest(requestQueueHandle, requestId, - IntPtr.Zero); + var statusCode = UnsafeNclNativeMethods.HttpApi.HttpCancelHttpRequest(Server.RequestQueue.Handle, + Request.RequestId, IntPtr.Zero); // Either the connection has already dropped, or the last write is in progress. // The requestId becomes invalid as soon as the last Content-Length write starts. // The only way to cancel now is with CancelIoEx. if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_CONNECTION_INVALID) { - _response.CancelLastWrite(requestQueueHandle); + Response.CancelLastWrite(); } } catch (ObjectDisposedException) diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestStream.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestStream.cs index bfbbf8cb1c..460471838a 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestStream.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestStream.cs @@ -26,6 +26,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace Microsoft.Net.Http.Server { @@ -48,6 +49,12 @@ namespace Microsoft.Net.Http.Server get { return _requestContext; } } + private SafeHandle RequestQueueHandle => RequestContext.Server.RequestQueue.Handle; + + private ulong RequestId => RequestContext.Request.RequestId; + + private ILogger Logger => RequestContext.Server.Logger; + public override bool CanSeek { get @@ -173,8 +180,8 @@ namespace Microsoft.Net.Http.Server statusCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, flags, (IntPtr)(pBuffer + offset), (uint)size, @@ -186,7 +193,7 @@ namespace Microsoft.Net.Http.Server if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF) { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "Read", exception); + LogHelper.LogException(Logger, "Read", exception); Abort(); throw exception; } @@ -256,8 +263,8 @@ namespace Microsoft.Net.Http.Server statusCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, flags, asyncResult.PinnedBuffer, (uint)size, @@ -266,7 +273,7 @@ namespace Microsoft.Net.Http.Server } catch (Exception e) { - LogHelper.LogException(_requestContext.Logger, "BeginRead", e); + LogHelper.LogException(Logger, "BeginRead", e); asyncResult.Dispose(); throw; } @@ -282,7 +289,7 @@ namespace Microsoft.Net.Http.Server else { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "BeginRead", exception); + LogHelper.LogException(Logger, "BeginRead", exception); Abort(); throw exception; } @@ -368,7 +375,7 @@ namespace Microsoft.Net.Http.Server var cancellationRegistration = default(CancellationTokenRegistration); if (cancellationToken.CanBeCanceled) { - cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext); + cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken); } asyncResult = new RequestStreamAsyncResult(this, null, null, buffer, offset, dataRead, cancellationRegistration); @@ -380,8 +387,8 @@ namespace Microsoft.Net.Http.Server statusCode = UnsafeNclNativeMethods.HttpApi.HttpReceiveRequestEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, flags, asyncResult.PinnedBuffer, (uint)size, @@ -392,7 +399,7 @@ namespace Microsoft.Net.Http.Server { asyncResult.Dispose(); Abort(); - LogHelper.LogException(_requestContext.Logger, "ReadAsync", e); + LogHelper.LogException(Logger, "ReadAsync", e); throw; } @@ -409,7 +416,7 @@ namespace Microsoft.Net.Http.Server else { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "ReadAsync", exception); + LogHelper.LogException(Logger, "ReadAsync", exception); Abort(); throw exception; } diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs index c7780b6b90..12d7a51bae 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs @@ -22,14 +22,12 @@ //------------------------------------------------------------------------------ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; @@ -38,26 +36,26 @@ using static Microsoft.Net.Http.Server.UnsafeNclNativeMethods; namespace Microsoft.Net.Http.Server { - public sealed unsafe class Response + public sealed class Response { private ResponseState _responseState; - private HeaderCollection _headers; private string _reasonPhrase; private ResponseStream _nativeStream; + private AuthenticationSchemes _authChallenges; + private TimeSpan? _cacheTtl; private long _expectedBodyLength; private BoundaryType _boundaryType; private HttpApi.HTTP_RESPONSE_V2 _nativeResponse; private IList, object>> _onStartingActions; private IList, object>> _onCompletedActions; - private RequestContext _requestContext; private bool _bufferingEnabled; internal Response(RequestContext requestContext) { // TODO: Verbose log - _requestContext = requestContext; - _headers = new HeaderCollection(); + RequestContext = requestContext; + Headers = new HeaderCollection(); Reset(); } @@ -65,14 +63,13 @@ namespace Microsoft.Net.Http.Server { if (_responseState >= ResponseState.StartedSending) { - _requestContext.Abort(); throw new InvalidOperationException("The response has already been sent. Request Aborted."); } // We haven't started yet, or we're just buffered, we can clear any data, headers, and state so // that we can start over (e.g. to write an error message). _nativeResponse = new HttpApi.HTTP_RESPONSE_V2(); - _headers.IsReadOnly = false; - _headers.Clear(); + Headers.IsReadOnly = false; + Headers.Clear(); _reasonPhrase = null; _boundaryType = BoundaryType.None; _nativeResponse.Response_V1.StatusCode = (ushort)HttpStatusCode.OK; @@ -81,10 +78,11 @@ namespace Microsoft.Net.Http.Server _responseState = ResponseState.Created; _onStartingActions = new List, object>>(); _onCompletedActions = new List, object>>(); - _bufferingEnabled = _requestContext.Server.BufferResponses; + _bufferingEnabled = RequestContext.Server.BufferResponses; _expectedBodyLength = 0; _nativeStream = null; - CacheTtl = null; + _cacheTtl = null; + _authChallenges = RequestContext.Server.AuthenticationManager.AuthenticationSchemes & ~AuthenticationSchemes.AllowAnonymous; } private enum ResponseState @@ -96,30 +94,19 @@ namespace Microsoft.Net.Http.Server Closed, } - private RequestContext RequestContext - { - get - { - return _requestContext; - } - } + private RequestContext RequestContext { get; } - private Request Request - { - get - { - return RequestContext.Request; - } - } + private Request Request => RequestContext.Request; public int StatusCode { get { return _nativeResponse.Response_V1.StatusCode; } set { + // Http.Sys automatically sends 100 Continue responses when you read from the request body. if (value <= 100 || 999 < value) { - throw new ArgumentOutOfRangeException("value", value, string.Format(Resources.Exception_InvalidStatusCode, value)); + throw new ArgumentOutOfRangeException(nameof(value), value, string.Format(Resources.Exception_InvalidStatusCode, value)); } CheckResponseStarted(); _nativeResponse.Response_V1.StatusCode = (ushort)value; @@ -157,26 +144,39 @@ namespace Microsoft.Net.Http.Server } } - internal string GetReasonPhrase(int statusCode) + /// + /// The authentication challenges that will be added to the response if the status code is 401. + /// This must be a subset of the AuthenticationSchemes enabled on the server. + /// + public AuthenticationSchemes AuthenticationChallenges + { + get { return _authChallenges; } + set + { + CheckResponseStarted(); + _authChallenges = value; + } + } + + private string GetReasonPhrase(int statusCode) { string reasonPhrase = ReasonPhrase; if (string.IsNullOrWhiteSpace(reasonPhrase)) { - // if the user hasn't set this, generated on the fly, if possible. - // We know this one is safe, no need to verify it as in the setter. + // If the user hasn't set this then it is generated on the fly if possible. reasonPhrase = HttpReasonPhrase.Get(statusCode) ?? string.Empty; } return reasonPhrase; } // We MUST NOT send message-body when we send responses with these Status codes - private static readonly int[] NoResponseBody = { 100, 101, 204, 205, 304 }; + private static readonly int[] StatusWithNoResponseBody = { 100, 101, 204, 205, 304 }; private static bool CanSendResponseBody(int responseCode) { - for (int i = 0; i < NoResponseBody.Length; i++) + for (int i = 0; i < StatusWithNoResponseBody.Length; i++) { - if (responseCode == NoResponseBody[i]) + if (responseCode == StatusWithNoResponseBody[i]) { return false; } @@ -184,10 +184,7 @@ namespace Microsoft.Net.Http.Server return true; } - public HeaderCollection Headers - { - get { return _headers; } - } + public HeaderCollection Headers { get; } internal long ExpectedBodyLength { @@ -261,6 +258,20 @@ namespace Microsoft.Net.Http.Server } } + /// + /// Enable kernel caching for the response with the given timeout. Http.Sys determines if the response + /// can be cached. + /// + public TimeSpan? CacheTtl + { + get { return _cacheTtl; } + set + { + CheckResponseStarted(); + _cacheTtl = value; + } + } + // should only be called from RequestContext internal void Dispose() { @@ -276,13 +287,17 @@ namespace Microsoft.Net.Http.Server _responseState = ResponseState.Closed; } - // old API, now private, and helper methods - internal BoundaryType BoundaryType { get { return _boundaryType; } } + /// + /// Indicates if the response status, reason, and headers are prepared to send and can + /// no longer be modified. This is caused by the first write to the response body. However, + /// the response may not have been flushed to the network yet if the body is buffered. + /// See HasStartedSending. + /// public bool HasStarted { get { return _responseState >= ResponseState.Started; } @@ -301,13 +316,14 @@ namespace Microsoft.Net.Http.Server get { return _responseState >= ResponseState.ComputedHeaders; } } + /// + /// Indicates the initial response has been flushed to the network and can no longer be modified or Reset. + /// public bool HasStartedSending { get { return _responseState >= ResponseState.StartedSending; } } - public TimeSpan? CacheTtl { get; set; } - private void EnsureResponseStream() { if (_nativeStream == null) @@ -389,11 +405,10 @@ namespace Microsoft.Net.Http.Server } var cachePolicy = new HttpApi.HTTP_CACHE_POLICY(); - var cacheTtl = CacheTtl; - if (cacheTtl.HasValue && cacheTtl.Value > TimeSpan.Zero) + if (_cacheTtl.HasValue && _cacheTtl.Value > TimeSpan.Zero) { cachePolicy.Policy = HttpApi.HTTP_CACHE_POLICY_TYPE.HttpCachePolicyTimeToLive; - cachePolicy.SecondsToLive = (uint)Math.Min(cacheTtl.Value.Ticks / TimeSpan.TicksPerSecond, Int32.MaxValue); + cachePolicy.SecondsToLive = (uint)Math.Min(_cacheTtl.Value.Ticks / TimeSpan.TicksPerSecond, Int32.MaxValue); } byte[] reasonPhraseBytes = HeaderEncoding.GetBytes(reasonPhrase); @@ -405,7 +420,7 @@ namespace Microsoft.Net.Http.Server { statusCode = HttpApi.HttpSendHttpResponse( - RequestContext.RequestQueueHandle, + RequestContext.Server.RequestQueue.Handle, Request.RequestId, (uint)flags, pResponse, @@ -471,7 +486,7 @@ namespace Microsoft.Net.Http.Server var responseContentLength = ContentLength; var responseCloseSet = Matches(Constants.Close, responseConnectionString); var responseChunkedSet = Matches(Constants.Chunked, transferEncodingString); - var statusCanHaveBody = CanSendResponseBody(_requestContext.Response.StatusCode); + var statusCanHaveBody = CanSendResponseBody(RequestContext.Response.StatusCode); // Determine if the connection will be kept alive or closed. var keepConnectionAlive = true; @@ -540,7 +555,7 @@ namespace Microsoft.Net.Http.Server return string.Equals(knownValue, input?.Trim(), StringComparison.OrdinalIgnoreCase); } - private List SerializeHeaders(bool isOpaqueUpgrade) + private unsafe List SerializeHeaders(bool isOpaqueUpgrade) { Headers.IsReadOnly = true; // Prohibit further modifications. HttpApi.HTTP_UNKNOWN_HEADER[] unknownHeaders = null; @@ -736,12 +751,9 @@ namespace Microsoft.Net.Http.Server } } - internal void CancelLastWrite(SafeHandle requestQueueHandle) + internal void CancelLastWrite() { - if (_nativeStream != null) - { - _nativeStream.CancelLastWrite(requestQueueHandle); - } + _nativeStream?.CancelLastWrite(); } public Task SendFileAsync(string path, long offset, long? count, CancellationToken cancel) diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs index fc0919602b..119f87d949 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs @@ -29,6 +29,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using static Microsoft.Net.Http.Server.UnsafeNclNativeMethods; namespace Microsoft.Net.Http.Server @@ -56,6 +57,12 @@ namespace Microsoft.Net.Http.Server get { return _requestContext; } } + private SafeHandle RequestQueueHandle => RequestContext.Server.RequestQueue.Handle; + + private ulong RequestId => RequestContext.Request.RequestId; + + private ILogger Logger => RequestContext.Server.Logger; + public override bool CanSeek { get @@ -125,7 +132,7 @@ namespace Microsoft.Net.Http.Server { _requestContext.Abort(); // This is logged rather than thrown because it is too late for an exception to be visible in user code. - LogHelper.LogError(_requestContext.Logger, "ResponseStream::Dispose", "Fewer bytes were written than were specified in the Content-Length."); + LogHelper.LogError(Logger, "ResponseStream::Dispose", "Fewer bytes were written than were specified in the Content-Length."); return; } @@ -153,8 +160,8 @@ namespace Microsoft.Net.Http.Server fixed (HttpApi.HTTP_DATA_CHUNK* pDataChunks = dataChunks) { statusCode = HttpApi.HttpSendResponseEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, (uint)flags, (ushort)dataChunks.Length, pDataChunks, @@ -182,7 +189,7 @@ namespace Microsoft.Net.Http.Server && (!endOfRequest || (statusCode != ErrorCodes.ERROR_CONNECTION_INVALID && statusCode != ErrorCodes.ERROR_INVALID_PARAMETER))) { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "Flush", exception); + LogHelper.LogException(Logger, "Flush", exception); Abort(); throw exception; } @@ -287,7 +294,7 @@ namespace Microsoft.Net.Http.Server var cancellationRegistration = default(CancellationTokenRegistration); if (cancellationToken.CanBeCanceled) { - cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext); + cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken); } var flags = ComputeLeftToWrite(); @@ -311,8 +318,8 @@ namespace Microsoft.Net.Http.Server else { statusCode = HttpApi.HttpSendResponseEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, (uint)flags, asyncResult.DataChunkCount, asyncResult.DataChunks, @@ -325,7 +332,7 @@ namespace Microsoft.Net.Http.Server } catch (Exception e) { - LogHelper.LogException(_requestContext.Logger, "FlushAsync", e); + LogHelper.LogException(Logger, "FlushAsync", e); asyncResult.Dispose(); Abort(); throw; @@ -341,7 +348,7 @@ namespace Microsoft.Net.Http.Server else { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "FlushAsync", exception); + LogHelper.LogException(Logger, "FlushAsync", exception); Abort(); throw exception; } @@ -408,8 +415,7 @@ namespace Microsoft.Net.Http.Server } if (_leftToWrite == long.MinValue) { - UnsafeNclNativeMethods.HttpApi.HTTP_VERB method = _requestContext.Request.GetKnownMethod(); - if (method == UnsafeNclNativeMethods.HttpApi.HTTP_VERB.HttpVerbHEAD) + if (_requestContext.Request.IsHeadMethod) { _leftToWrite = 0; } @@ -578,7 +584,7 @@ namespace Microsoft.Net.Http.Server var cancellationRegistration = default(CancellationTokenRegistration); if (cancellationToken.CanBeCanceled) { - cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext); + cancellationRegistration = RequestContext.RegisterForCancellation(cancellationToken); } uint statusCode; @@ -615,8 +621,8 @@ namespace Microsoft.Net.Http.Server { // TODO: If opaque then include the buffer data flag. statusCode = HttpApi.HttpSendResponseEntityBody( - _requestContext.RequestQueueHandle, - _requestContext.RequestId, + RequestQueueHandle, + RequestId, (uint)flags, asyncResult.DataChunkCount, asyncResult.DataChunks, @@ -629,7 +635,7 @@ namespace Microsoft.Net.Http.Server } catch (Exception e) { - LogHelper.LogException(_requestContext.Logger, "SendFileAsync", e); + LogHelper.LogException(Logger, "SendFileAsync", e); asyncResult.Dispose(); Abort(); throw; @@ -645,7 +651,7 @@ namespace Microsoft.Net.Http.Server else { Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); - LogHelper.LogException(_requestContext.Logger, "SendFileAsync", exception); + LogHelper.LogException(Logger, "SendFileAsync", exception); Abort(); throw exception; } @@ -713,12 +719,12 @@ namespace Microsoft.Net.Http.Server // Sync can only be Canceled by CancelSynchronousIo, but we don't attempt this right now. [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "It is safe to ignore the return value on a cancel operation because the connection is being closed")] - internal unsafe void CancelLastWrite(SafeHandle requestQueueHandle) + internal unsafe void CancelLastWrite() { ResponseStreamAsyncResult asyncState = _lastWrite; if (asyncState != null && !asyncState.IsCompleted) { - UnsafeNclNativeMethods.CancelIoEx(requestQueueHandle, asyncState.NativeOverlapped); + UnsafeNclNativeMethods.CancelIoEx(RequestQueueHandle, asyncState.NativeOverlapped); } } diff --git a/src/Microsoft.Net.Http.Server/TimeoutManager.cs b/src/Microsoft.Net.Http.Server/TimeoutManager.cs index 91eb95af0b..94f3625fc0 100644 --- a/src/Microsoft.Net.Http.Server/TimeoutManager.cs +++ b/src/Microsoft.Net.Http.Server/TimeoutManager.cs @@ -22,7 +22,6 @@ // ----------------------------------------------------------------------- using System; -using System.Diagnostics; using System.Runtime.InteropServices; namespace Microsoft.Net.Http.Server @@ -53,8 +52,6 @@ namespace Microsoft.Net.Http.Server // // No initialization is required because a value of zero indicates that system defaults should be used. _timeouts = new int[5]; - - LoadConfigurationSettings(); } #region Properties @@ -72,11 +69,11 @@ namespace Microsoft.Net.Http.Server { get { - return GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody); + return GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody); } set { - SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody, value); + SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.EntityBody, value); } } @@ -95,11 +92,11 @@ namespace Microsoft.Net.Http.Server { get { - return GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody); + return GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody); } set { - SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody, value); + SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.DrainEntityBody, value); } } @@ -113,11 +110,11 @@ namespace Microsoft.Net.Http.Server { get { - return GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue); + return GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue); } set { - SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue, value); + SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.RequestQueue, value); } } @@ -132,11 +129,11 @@ namespace Microsoft.Net.Http.Server { get { - return GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection); + return GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection); } set { - SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection, value); + SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.IdleConnection, value); } } @@ -152,17 +149,19 @@ namespace Microsoft.Net.Http.Server { get { - return GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait); + return GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait); } set { - SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait, value); + SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait, value); } } /// /// The minimum send rate, in bytes-per-second, for the response. The default response send rate is 150 /// bytes-per-second. + /// + /// Use 0 to indicate that system defaults should be used. /// /// To disable this timer set it to UInt32.MaxValue /// @@ -181,60 +180,27 @@ namespace Microsoft.Net.Http.Server throw new ArgumentOutOfRangeException("value"); } - SetServerTimeout(_timeouts, (uint)value); + SetServerTimeouts(_timeouts, (uint)value); _minSendBytesPerSecond = (uint)value; } } #endregion Properties - // Initial values come from the config. The values can then be overridden using this public API. - private void LoadConfigurationSettings() - { - long[] configTimeouts = new long[_timeouts.Length + 1]; // SettingsSectionInternal.Section.HttpListenerTimeouts; - Debug.Assert(configTimeouts != null); - Debug.Assert(configTimeouts.Length == (_timeouts.Length + 1)); - - bool setNonDefaults = false; - for (int i = 0; i < _timeouts.Length; i++) - { - if (configTimeouts[i] != 0) - { - Debug.Assert(configTimeouts[i] <= ushort.MaxValue, "Timeout out of range: " + configTimeouts[i]); - _timeouts[i] = (int)configTimeouts[i]; - setNonDefaults = true; - } - } - - if (configTimeouts[5] != 0) - { - Debug.Assert(configTimeouts[5] <= uint.MaxValue, "Timeout out of range: " + configTimeouts[5]); - _minSendBytesPerSecond = (uint)configTimeouts[5]; - setNonDefaults = true; - } - - if (setNonDefaults) - { - SetServerTimeout(_timeouts, _minSendBytesPerSecond); - } - } - #region Helpers - private TimeSpan GetTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE type) + private TimeSpan GetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE type) { // Since we maintain local state, GET is local. return new TimeSpan(0, 0, (int)_timeouts[(int)type]); } - private void SetTimespanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE type, TimeSpan value) + private void SetTimeSpanTimeout(UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE type, TimeSpan value) { - Int64 timeoutValue; - // All timeouts are defined as USHORT in native layer (except MinSendRate, which is ULONG). Make sure that // timeout value is within range. - timeoutValue = Convert.ToInt64(value.TotalSeconds); + var timeoutValue = Convert.ToInt64(value.TotalSeconds); if (timeoutValue < 0 || timeoutValue > ushort.MaxValue) { @@ -243,17 +209,15 @@ namespace Microsoft.Net.Http.Server // Use local state to get values for other timeouts. Call into the native layer and if that // call succeeds, update local state. - - int[] currentTimeouts = _timeouts; - currentTimeouts[(int)type] = (int)timeoutValue; - SetServerTimeout(currentTimeouts, _minSendBytesPerSecond); + var newTimeouts = (int[])_timeouts.Clone(); + newTimeouts[(int)type] = (int)timeoutValue; + SetServerTimeouts(newTimeouts, _minSendBytesPerSecond); _timeouts[(int)type] = (int)timeoutValue; } - private unsafe void SetServerTimeout(int[] timeouts, uint minSendBytesPerSecond) + private unsafe void SetServerTimeouts(int[] timeouts, uint minSendBytesPerSecond) { - UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_LIMIT_INFO timeoutinfo = - new UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_LIMIT_INFO(); + var timeoutinfo = new UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_LIMIT_INFO(); timeoutinfo.Flags = UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_PROPERTY_FLAG_PRESENT; timeoutinfo.DrainEntityBody = @@ -268,7 +232,7 @@ namespace Microsoft.Net.Http.Server (ushort)timeouts[(int)UnsafeNclNativeMethods.HttpApi.HTTP_TIMEOUT_TYPE.HeaderWait]; timeoutinfo.MinSendRate = minSendBytesPerSecond; - IntPtr infoptr = new IntPtr(&timeoutinfo); + var infoptr = new IntPtr(&timeoutinfo); _server.UrlGroup.SetProperty( UnsafeNclNativeMethods.HttpApi.HTTP_SERVER_PROPERTY.HttpServerTimeoutsProperty, diff --git a/src/Microsoft.Net.Http.Server/WebListener.cs b/src/Microsoft.Net.Http.Server/WebListener.cs index 8a7744f269..960373d82e 100644 --- a/src/Microsoft.Net.Http.Server/WebListener.cs +++ b/src/Microsoft.Net.Http.Server/WebListener.cs @@ -138,17 +138,6 @@ namespace Microsoft.Net.Http.Server get { return _logger; } } - public UrlPrefixCollection UrlPrefixes - { - get { return _urlPrefixes; } - } - - public bool BufferResponses - { - get { return _bufferResponses; } - set { _bufferResponses = value; } - } - internal UrlGroup UrlGroup { get { return _urlGroup; } @@ -164,29 +153,7 @@ namespace Microsoft.Net.Http.Server get { return _disconnectListener; } } - /// - /// Exposes the Http.Sys timeout configurations. These may also be configured in the registry. - /// - public TimeoutManager TimeoutManager - { - get { return _timeoutManager; } - } - - public AuthenticationManager AuthenticationManager - { - get { return _authManager; } - } - - internal static bool IsSupported - { - get { return UnsafeNclNativeMethods.HttpApi.Supported; } - } - - public bool IsListening - { - get { return _state == State.Started; } - } - + // TODO: https://github.com/aspnet/WebListener/issues/173 internal bool IgnoreWriteExceptions { get { return _ignoreWriteExceptions; } @@ -197,6 +164,38 @@ namespace Microsoft.Net.Http.Server } } + public UrlPrefixCollection UrlPrefixes + { + get { return _urlPrefixes; } + } + + public bool BufferResponses + { + get { return _bufferResponses; } + set { _bufferResponses = value; } + } + + /// + /// Exposes the Http.Sys timeout configurations. These may also be configured in the registry. + /// + public TimeoutManager TimeoutManager + { + get { return _timeoutManager; } + } + + /// + /// Http.Sys authentication settings. + /// + public AuthenticationManager AuthenticationManager + { + get { return _authManager; } + } + + public bool IsListening + { + get { return _state == State.Started; } + } + /// /// Sets the maximum number of requests that will be queued up in Http.Sys. /// @@ -208,6 +207,8 @@ namespace Microsoft.Net.Http.Server { throw new ArgumentOutOfRangeException("limit", limit, string.Empty); } + + // Don't try to change it if the new limit is the same if ((!_requestQueueLength.HasValue && limit == DefaultRequestQueueLength) || (_requestQueueLength.HasValue && limit == _requestQueueLength.Value)) { @@ -218,6 +219,9 @@ namespace Microsoft.Net.Http.Server _requestQueue.SetLengthLimit(_requestQueueLength.Value); } + /// + /// Start accepting incoming requests. + /// public void Start() { CheckDisposed(); @@ -298,7 +302,6 @@ namespace Microsoft.Net.Http.Server Dispose(true); } - // old API, now private, and helper methods private void Dispose(bool disposing) { if (!disposing) @@ -350,31 +353,10 @@ namespace Microsoft.Net.Http.Server _serverSession.Dispose(); } - internal unsafe bool ValidateRequest(NativeRequestContext requestMemory) - { - // Block potential DOS attacks - if (requestMemory.RequestBlob->Headers.UnknownHeaderCount > UnknownHeaderLimit) - { - SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.BadRequest, authChallenges: null); - return false; - } - return true; - } - - internal unsafe bool ValidateAuth(NativeRequestContext requestMemory) - { - var requestV2 = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)requestMemory.RequestBlob; - if (!AuthenticationManager.AllowAnonymous && !AuthenticationManager.CheckAuthenticated(requestV2->pRequestInfo)) - { - SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.Unauthorized, - AuthenticationManager.GenerateChallenges(AuthenticationManager.AuthenticationSchemes)); - return false; - } - return true; - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposed by callback")] - public Task GetContextAsync() + /// + /// Accept a request from the incoming request queue. + /// + public Task AcceptAsync() { AsyncAcceptContext asyncResult = null; try @@ -404,6 +386,29 @@ namespace Microsoft.Net.Http.Server return asyncResult.Task; } + internal unsafe bool ValidateRequest(NativeRequestContext requestMemory) + { + // Block potential DOS attacks + if (requestMemory.RequestBlob->Headers.UnknownHeaderCount > UnknownHeaderLimit) + { + SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.BadRequest, authChallenges: null); + return false; + } + return true; + } + + internal unsafe bool ValidateAuth(NativeRequestContext requestMemory) + { + var requestV2 = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)requestMemory.RequestBlob; + if (!AuthenticationManager.AllowAnonymous && !AuthenticationManager.CheckAuthenticated(requestV2->pRequestInfo)) + { + SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.Unauthorized, + AuthenticationManager.GenerateChallenges(AuthenticationManager.AuthenticationSchemes)); + return false; + } + return true; + } + private unsafe void SendError(ulong requestId, HttpStatusCode httpStatusCode, IList authChallenges) { UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_V2 httpResponse = new UnsafeNclNativeMethods.HttpApi.HTTP_RESPONSE_V2(); @@ -494,7 +499,7 @@ namespace Microsoft.Net.Http.Server if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { // if we fail to send a 401 something's seriously wrong, abort the request - RequestContext.CancelRequest(_requestQueue.Handle, requestId); + UnsafeNclNativeMethods.HttpApi.HttpCancelHttpRequest(_requestQueue.Handle, requestId, IntPtr.Zero); } } finally diff --git a/test/Microsoft.AspNetCore.Server.WebListener.FunctionalTests/project.json b/test/Microsoft.AspNetCore.Server.WebListener.FunctionalTests/project.json index e8ea925fcf..c79eb2c3f8 100644 --- a/test/Microsoft.AspNetCore.Server.WebListener.FunctionalTests/project.json +++ b/test/Microsoft.AspNetCore.Server.WebListener.FunctionalTests/project.json @@ -1,4 +1,8 @@ { + "buildOptions": { + "warningsAsErrors": true, + "keyFile": "../../tools/Key.snk" + }, "testRunner": "xunit", "dependencies": { "dotnet-test-xunit": "2.2.0-*", diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/AuthenticationTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/AuthenticationTests.cs index 2721e6cab1..3ad4c842ae 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/AuthenticationTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/AuthenticationTests.cs @@ -25,16 +25,16 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.False(context.User.Identity.IsAuthenticated); if (authType == AuthenticationSchemes.AllowAnonymous) { - Assert.Equal(AuthenticationSchemes.None, context.AuthenticationChallenges); + Assert.Equal(AuthenticationSchemes.None, context.Response.AuthenticationChallenges); } else { - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); } context.Dispose(); @@ -57,7 +57,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var contextTask = server.GetContextAsync(); // Fails when the server shuts down, the challenge happens internally. + var contextTask = server.AcceptAsync(); // Fails when the server shuts down, the challenge happens internally. var response = await responseTask; Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.ToString(), StringComparer.OrdinalIgnoreCase); @@ -77,10 +77,10 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.False(context.User.Identity.IsAuthenticated); - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); context.Response.StatusCode = 401; context.Dispose(); @@ -104,10 +104,10 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.False(context.User.Identity.IsAuthenticated); - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); context.Response.StatusCode = 401; context.Dispose(); @@ -130,17 +130,17 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, useDefaultCredentials: true); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.False(context.User.Identity.IsAuthenticated); - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); context.Response.StatusCode = 401; context.Dispose(); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.True(context.User.Identity.IsAuthenticated); - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); context.Dispose(); var response = await responseTask; @@ -161,10 +161,10 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, useDefaultCredentials: true); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.True(context.User.Identity.IsAuthenticated); - Assert.Equal(authType, context.AuthenticationChallenges); + Assert.Equal(authType, context.Response.AuthenticationChallenges); context.Dispose(); var response = await responseTask; @@ -181,10 +181,10 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, useDefaultCredentials: true); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.True(context.User.Identity.IsAuthenticated); - Assert.Equal(AuthenticationSchemes.Kerberos, context.AuthenticationChallenges); + Assert.Equal(AuthenticationSchemes.Kerberos, context.Response.AuthenticationChallenges); context.Dispose(); var response = await responseTask; @@ -201,10 +201,10 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.NotNull(context.User); Assert.False(context.User.Identity.IsAuthenticated); - Assert.Equal(AuthenticationSchemes.Kerberos, context.AuthenticationChallenges); + Assert.Equal(AuthenticationSchemes.Kerberos, context.Response.AuthenticationChallenges); context.Response.StatusCode = 401; context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/HttpsTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/HttpsTests.cs index 73f915d3b8..ad25c21142 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/HttpsTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/HttpsTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(Address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); string response = await responseTask; @@ -36,7 +36,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(Address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] body = Encoding.UTF8.GetBytes("Hello World"); context.Response.ContentLength = body.Length; await context.Response.Body.WriteAsync(body, 0, body.Length); @@ -54,7 +54,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(Address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); string input = new StreamReader(context.Request.Body).ReadToEnd(); Assert.Equal("Hello World", input); context.Response.ContentLength = 11; @@ -75,7 +75,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(Address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cert = await context.Request.GetClientCertificateAsync(); Assert.Null(cert); context.Dispose(); @@ -94,7 +94,7 @@ namespace Microsoft.Net.Http.Server Assert.NotNull(clientCert); Task responseTask = SendRequestAsync(Address, clientCert); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cert = await context.Request.GetClientCertificateAsync(); Assert.NotNull(cert); context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/OpaqueUpgradeTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/OpaqueUpgradeTests.cs index d85688e521..274ab452e0 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/OpaqueUpgradeTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/OpaqueUpgradeTests.cs @@ -22,7 +22,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] body = Encoding.UTF8.GetBytes("Hello World"); context.Response.Body.Write(body, 0, body.Length); @@ -44,7 +44,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendOpaqueRequestAsync("GET", address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.True(context.IsUpgradableRequest); context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket Stream serverStream = await context.UpgradeAsync(); @@ -88,7 +88,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendOpaqueRequestAsync(method, address, extraHeader); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.True(context.IsUpgradableRequest); context.Response.Headers["Upgrade"] = "WebSocket"; // Win8.1 blocks anything but WebSocket Stream serverStream = await context.UpgradeAsync(); @@ -128,7 +128,7 @@ namespace Microsoft.Net.Http.Server using (var server = Utilities.CreateHttpServer(out address)) { var clientTask = SendOpaqueRequestAsync(method, address, extraHeader); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.False(context.IsUpgradableRequest); context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestBodyTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestBodyTests.cs index d647cd70d9..51229b93bb 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestBodyTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestBodyTests.cs @@ -22,7 +22,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[100]; int read = context.Request.Body.Read(input, 0, input.Length); context.Response.ContentLength = read; @@ -41,7 +41,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[100]; int read = await context.Request.Body.ReadAsync(input, 0, input.Length); context.Response.ContentLength = read; @@ -60,7 +60,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[100]; int read = context.Request.Body.EndRead(context.Request.Body.BeginRead(input, 0, input.Length, null, null)); context.Response.ContentLength = read; @@ -80,7 +80,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[100]; Assert.Throws("buffer", () => context.Request.Body.Read(null, 0, 1)); Assert.Throws("offset", () => context.Request.Body.Read(input, -1, 1)); @@ -105,7 +105,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; int read = context.Request.Body.Read(input, 0, input.Length); Assert.Equal(5, read); @@ -128,7 +128,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; int read = await context.Request.Body.ReadAsync(input, 0, input.Length); Assert.Equal(5, read); @@ -150,7 +150,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendSocketRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[11]; int read = await context.Request.Body.ReadAsync(input, 0, input.Length); Assert.Equal(10, read); @@ -176,7 +176,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; var cts = new CancellationTokenSource(); @@ -201,7 +201,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; var cts = new CancellationTokenSource(); int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token); @@ -225,7 +225,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(5)); @@ -250,7 +250,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; var cts = new CancellationTokenSource(); int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token); @@ -275,7 +275,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; var cts = new CancellationTokenSource(); int read = await context.Request.Body.ReadAsync(input, 0, input.Length, cts.Token); @@ -303,7 +303,7 @@ namespace Microsoft.Net.Http.Server var client = new HttpClient(); var responseTask = client.PostAsync(address, content); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] input = new byte[10]; int read = await context.Request.Body.ReadAsync(input, 0, input.Length, context.DisconnectToken); Assert.False(context.DisconnectToken.IsCancellationRequested); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestHeaderTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestHeaderTests.cs index 40980cfbd3..c3b1c90caa 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestHeaderTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestHeaderTests.cs @@ -20,7 +20,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var requestHeaders = context.Request.Headers; // NOTE: The System.Net client only sends the Connection: keep-alive header on the first connection per service-point. // Assert.Equal(2, requestHeaders.Count); @@ -46,7 +46,7 @@ namespace Microsoft.Net.Http.Server string[] customValues = new string[] { "custom1, and custom2", "custom3" }; Task responseTask = SendRequestAsync(address, "Custom-Header", customValues); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var requestHeaders = context.Request.Headers; Assert.Equal(4, requestHeaders.Count); Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]); @@ -73,7 +73,7 @@ namespace Microsoft.Net.Http.Server string[] customValues = new string[] { "custom1, and custom测试2", "custom3" }; Task responseTask = SendRequestAsync(address, "Custom-Header", customValues); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var requestHeaders = context.Request.Headers; Assert.Equal(4, requestHeaders.Count); Assert.Equal(new Uri(address).Authority, requestHeaders["Host"]); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestTests.cs index ac7b14d0c6..d69ac9ee81 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/RequestTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/RequestTests.cs @@ -20,7 +20,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(root + "/basepath/SomePath?SomeQuery"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); // General fields var request = context.Request; @@ -64,7 +64,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(root + requestPath); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); // General fields var request = context.Request; @@ -92,7 +92,7 @@ namespace Microsoft.Net.Http.Server using (var server = Utilities.CreateHttpServerReturnRoot("/", out root)) { var responseTask = SendSocketRequestAsync(root, requestPath); - var contextTask = server.GetContextAsync(); + var contextTask = server.AcceptAsync(); var response = await responseTask; var responseStatusCode = response.Substring(9); // Skip "HTTP/1.1 " Assert.Equal("400", responseStatusCode); @@ -106,7 +106,7 @@ namespace Microsoft.Net.Http.Server using (var server = Utilities.CreateHttpServerReturnRoot("/", out root)) { var responseTask = SendSocketRequestAsync(root, "/%252F"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Equal("/%2F", context.Request.Path); } } @@ -142,7 +142,7 @@ namespace Microsoft.Net.Http.Server Task responseTask = SendRequestAsync(root + requestUri); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var request = context.Request; Assert.Equal(expectedPath, request.Path); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseBodyTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseBodyTests.cs index 9b990f777c..9a802091f1 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseBodyTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseBodyTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ShouldBuffer = true; context.Response.Body.Write(new byte[10], 0, 10); await context.Response.Body.WriteAsync(new byte[10], 0, 10); @@ -47,7 +47,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ShouldBuffer = false; context.Response.Body.Write(new byte[10], 0, 10); await context.Response.Body.WriteAsync(new byte[10], 0, 10); @@ -71,7 +71,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Body.Write(new byte[10], 0, 10); context.Response.Body.Flush(); await context.Response.Body.WriteAsync(new byte[10], 0, 10); @@ -94,7 +94,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["transfeR-Encoding"] = "CHunked"; Stream stream = context.Response.Body; var responseBytes = Encoding.ASCII.GetBytes("10\r\nManually Chunked\r\n0\r\n\r\n"); @@ -119,7 +119,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 30 "; Stream stream = context.Response.Body; #if NET451 @@ -150,12 +150,12 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 20 "; context.Dispose(); #if !NETCOREAPP1_0 // HttpClient retries the request because it didn't get a response. - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 20 "; context.Dispose(); #endif @@ -171,13 +171,13 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 20 "; context.Response.Body.Write(new byte[5], 0, 5); context.Dispose(); #if !NETCOREAPP1_0 // HttpClient retries the request because it didn't get a response. - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 20 "; context.Response.Body.Write(new byte[5], 0, 5); context.Dispose(); @@ -194,14 +194,14 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 10 "; context.Response.Body.Write(new byte[5], 0, 5); Assert.Throws(() => context.Response.Body.Write(new byte[6], 0, 6)); context.Dispose(); #if !NETCOREAPP1_0 // HttpClient retries the request because it didn't get a response. - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 10 "; context.Response.Body.Write(new byte[5], 0, 5); Assert.Throws(() => context.Response.Body.Write(new byte[6], 0, 6)); @@ -219,7 +219,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = " 10 "; context.Response.Body.Write(new byte[10], 0, 10); Assert.Throws(() => context.Response.Body.Write(new byte[6], 0, 6)); @@ -244,7 +244,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Body.Write(new byte[10], 0, 0); Assert.True(context.Response.HasStarted); await context.Response.Body.WriteAsync(new byte[10], 0, 0); @@ -268,7 +268,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ShouldBuffer = true; for (int i = 0; i < 4; i++) { @@ -299,7 +299,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ShouldBuffer = true; for (int i = 0; i < 4; i++) { @@ -330,7 +330,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cts = new CancellationTokenSource(); // First write sends headers await context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token); @@ -351,7 +351,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(1)); // First write sends headers @@ -373,7 +373,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cts = new CancellationTokenSource(); cts.Cancel(); // First write sends headers @@ -395,7 +395,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var cts = new CancellationTokenSource(); // First write sends headers await context.Response.Body.WriteAsync(new byte[10], 0, 10, cts.Token); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseCachingTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseCachingTests.cs index 4073056695..f4b5272d41 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseCachingTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseCachingTests.cs @@ -30,7 +30,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -43,7 +43,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -64,7 +64,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -93,7 +93,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -124,7 +124,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.Headers["age"] = "12345"; @@ -156,7 +156,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(0); @@ -169,7 +169,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -190,7 +190,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromMilliseconds(900); @@ -203,7 +203,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -224,7 +224,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(-10); @@ -237,7 +237,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -258,7 +258,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.MaxValue; @@ -285,7 +285,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -315,7 +315,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -329,7 +329,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; context.Dispose(); @@ -348,7 +348,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -363,7 +363,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; context.Dispose(); @@ -382,7 +382,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength = 10; @@ -411,7 +411,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -425,7 +425,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; context.Dispose(); @@ -444,7 +444,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength =_fileLength; @@ -482,7 +482,7 @@ namespace Microsoft.Net.Http.Server var responseTask = SendRequestAsync(address + status); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = status; context.Response.Headers["x-request-count"] = status.ToString(); context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache @@ -533,7 +533,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, method); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = context.Request.Method + "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -546,7 +546,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address, method); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = context.Request.Method + "2"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -592,7 +592,7 @@ namespace Microsoft.Net.Http.Server // Cache the first response var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = context.Request.Method + "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -606,7 +606,7 @@ namespace Microsoft.Net.Http.Server // Try to clear the cache with a second request responseTask = SendRequestAsync(address, method); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = context.Request.Method + "2"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Dispose(); @@ -637,7 +637,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "GET", "x-vary", "vary1"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.Headers["vary"] = "x-vary"; @@ -668,7 +668,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -681,7 +681,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123"); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Dispose(); @@ -702,7 +702,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -715,7 +715,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address, "GET", "Authorization", "Basic abc123"); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "2"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Dispose(); @@ -738,7 +738,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "GET", "Pragma", "no-cache"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -767,7 +767,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -795,7 +795,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "GET", "Cache-Control", "no-cache"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -823,7 +823,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -851,7 +851,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -879,7 +879,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.CacheTtl = TimeSpan.FromSeconds(10); @@ -906,7 +906,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "GET", "Range", "bytes=0-10"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 206; context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache @@ -923,7 +923,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address, "GET", "Range", "bytes=0-10"); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Response.StatusCode = 206; context.Response.Headers["x-request-count"] = "2"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache @@ -951,7 +951,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength = 100; @@ -981,7 +981,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength = 100; @@ -1011,7 +1011,7 @@ namespace Microsoft.Net.Http.Server var responseLength = _fileLength / 2; // Make sure it handles partial files. var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength = responseLength; @@ -1043,7 +1043,7 @@ namespace Microsoft.Net.Http.Server var responseLength = _fileLength / 2; // Make sure it handles partial files. var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["x-request-count"] = "1"; context.Response.Headers["content-type"] = "some/thing"; // Http.sys requires a content-type to cache context.Response.ContentLength = responseLength; diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs index a788e2ffb4..0374617f2f 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs @@ -22,7 +22,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -44,7 +44,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, usehttp11: false); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -67,7 +67,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendHeadRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -89,7 +89,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendHeadRequestAsync(address, usehttp11: false); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -112,7 +112,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendHeadRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ContentLength = 20; context.Dispose(); @@ -135,7 +135,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 204; // No Content context.Dispose(); @@ -158,7 +158,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendHeadRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 204; // No Content context.Dispose(); @@ -182,7 +182,7 @@ namespace Microsoft.Net.Http.Server WebRequest request = WebRequest.Create(address); Task responseTask = request.GetResponseAsync(); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["WWW-Authenticate"] = "custom1"; context.Dispose(); @@ -207,7 +207,7 @@ namespace Microsoft.Net.Http.Server WebRequest request = WebRequest.Create(address); Task responseTask = request.GetResponseAsync(); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["WWW-Authenticate"] = new[] { "custom1, and custom2", "custom3" }; context.Dispose(); @@ -236,7 +236,7 @@ namespace Microsoft.Net.Http.Server WebRequest request = WebRequest.Create(address); Task responseTask = request.GetResponseAsync(); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["Custom-Header1"] = new[] { "custom1, and custom2", "custom3" }; context.Dispose(); @@ -264,7 +264,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["Connection"] = "Close"; context.Dispose(); @@ -284,7 +284,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address, usehttp11: false); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -307,7 +307,7 @@ namespace Microsoft.Net.Http.Server request.Version = new Version(1, 0); Task responseTask = client.SendAsync(request); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["Transfer-Encoding"] = "chunked"; var responseBytes = Encoding.ASCII.GetBytes("10\r\nManually Chunked\r\n0\r\n\r\n"); @@ -335,7 +335,7 @@ namespace Microsoft.Net.Http.Server // Http.Sys does not support 1.0 keep-alives. Task responseTask = SendRequestAsync(address, usehttp11: false, sendKeepAlive: true); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); HttpResponseMessage response = await responseTask; @@ -353,7 +353,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["Custom1"] = new[] { "value1a", "value1b" }; @@ -389,7 +389,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; responseHeaders["Custom1"] = new[] { "value1a", "value1b" }; @@ -443,7 +443,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var responseHeaders = context.Response.Headers; diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseSendFileTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseSendFileTests.cs index 4428dfc086..6ed772dc29 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseSendFileTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseSendFileTests.cs @@ -32,7 +32,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await Assert.ThrowsAsync(() => context.Response.SendFileAsync("Missing.txt", 0, null, CancellationToken.None)); context.Dispose(); @@ -49,7 +49,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); context.Dispose(); @@ -70,7 +70,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(RelativeFilePath, 0, null, CancellationToken.None); context.Dispose(); @@ -91,7 +91,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); context.Dispose(); @@ -112,7 +112,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); context.Dispose(); @@ -134,7 +134,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, FileLength / 2, CancellationToken.None); context.Dispose(); @@ -155,7 +155,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await Assert.ThrowsAsync( () => context.Response.SendFileAsync(AbsoluteFilePath, 1234567, null, CancellationToken.None)); context.Dispose(); @@ -172,7 +172,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await Assert.ThrowsAsync( () => context.Response.SendFileAsync(AbsoluteFilePath, 0, 1234567, CancellationToken.None)); context.Dispose(); @@ -189,7 +189,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None); context.Dispose(); @@ -214,7 +214,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); await context.Response.SendFileAsync(emptyFilePath, 0, null, CancellationToken.None); Assert.True(context.Response.HasStartedSending); await context.Response.Body.WriteAsync(new byte[10], 0, 10, CancellationToken.None); @@ -238,7 +238,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = FileLength.ToString(); await context.Response.SendFileAsync(AbsoluteFilePath, 0, null, CancellationToken.None); @@ -260,7 +260,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = "10"; await context.Response.SendFileAsync(AbsoluteFilePath, 0, 10, CancellationToken.None); context.Dispose(); @@ -283,7 +283,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.Headers["Content-lenGth"] = "0"; await context.Response.SendFileAsync(AbsoluteFilePath, 0, 0, CancellationToken.None); context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseTests.cs index 4e46f19ef7..12b379c22c 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Equal(200, context.Response.StatusCode); context.Dispose(); @@ -38,7 +38,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 201; // TODO: env["owin.ResponseProtocol"] = "HTTP/1.0"; // Http.Sys ignores this value context.Dispose(); @@ -59,7 +59,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 201; context.Response.ReasonPhrase = "CustomReasonPhrase"; // TODO: env["owin.ResponseProtocol"] = "HTTP/1.0"; // Http.Sys ignores this value @@ -81,7 +81,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.StatusCode = 901; context.Dispose(); @@ -100,7 +100,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Throws(() => { context.Response.StatusCode = 100; }); context.Dispose(); @@ -116,7 +116,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Throws(() => { context.Response.StatusCode = 0; }); context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ServerTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ServerTests.cs index eebf509011..6b444e4ba6 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ServerTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ServerTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); var response = await responseTask; @@ -39,7 +39,7 @@ namespace Microsoft.Net.Http.Server { Task responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Response.ContentLength = 11; using (var writer = new StreamWriter(context.Response.Body)) { @@ -59,7 +59,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address, "Hello World"); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); string input = new StreamReader(context.Request.Body).ReadToEnd(); Assert.Equal("Hello World", input); context.Response.ContentLength = 11; @@ -86,7 +86,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = client.GetAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var ct = context.DisconnectToken; Assert.True(ct.CanBeCanceled, "CanBeCanceled"); Assert.False(ct.IsCancellationRequested, "IsCancellationRequested"); @@ -115,7 +115,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var ct = context.DisconnectToken; Assert.True(ct.CanBeCanceled, "CanBeCanceled"); Assert.False(ct.IsCancellationRequested, "IsCancellationRequested"); @@ -125,7 +125,7 @@ namespace Microsoft.Net.Http.Server Assert.True(ct.IsCancellationRequested, "IsCancellationRequested"); #if !NETCOREAPP1_0 // HttpClient re-tries the request because it doesn't know if the request was received. - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); context.Abort(); #endif await Assert.ThrowsAsync(() => responseTask); @@ -143,7 +143,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); var ct = context.DisconnectToken; Assert.True(ct.CanBeCanceled, "CanBeCanceled"); Assert.False(ct.IsCancellationRequested, "IsCancellationRequested"); @@ -174,7 +174,7 @@ namespace Microsoft.Net.Http.Server server.SetRequestQueueLimit(1001); var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); context.Dispose(); var response = await responseTask; @@ -190,7 +190,7 @@ namespace Microsoft.Net.Http.Server { var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Equal(string.Empty, context.Request.PathBase); Assert.Equal("/", context.Request.Path); context.Dispose(); @@ -203,7 +203,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); Assert.Equal("/pathbase", context.Request.PathBase); Assert.Equal("/", context.Request.Path); context.Dispose(); @@ -223,7 +223,7 @@ namespace Microsoft.Net.Http.Server server.UrlPrefixes.Add(address); var responseTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.Equal("/pathbase", context.Request.PathBase); Assert.Equal("/", context.Request.Path); context.Dispose(); @@ -235,7 +235,7 @@ namespace Microsoft.Net.Http.Server responseTask = SendRequestAsync(address); - context = await server.GetContextAsync(); + context = await server.AcceptAsync(); Assert.Equal(string.Empty, context.Request.PathBase); Assert.Equal("/pathbase/", context.Request.Path); context.Dispose(); diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/WebSocketTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/WebSocketTests.cs index 6271d2ae93..96bbedaea8 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/WebSocketTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/WebSocketTests.cs @@ -22,7 +22,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendRequestAsync(address); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); byte[] body = Encoding.UTF8.GetBytes("Hello World"); context.Response.Body.Write(body, 0, body.Length); @@ -43,7 +43,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendWebSocketRequestAsync(ConvertToWebSocketAddress(address)); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.True(context.IsUpgradableRequest); WebSocket serverWebSocket = await context.AcceptWebSocketAsync(); WebSocket clientWebSocket = await clientTask; @@ -61,7 +61,7 @@ namespace Microsoft.Net.Http.Server { Task clientTask = SendWebSocketRequestAsync(ConvertToWebSocketAddress(address)); - var context = await server.GetContextAsync(); + var context = await server.AcceptAsync(); Assert.True(context.IsWebSocketRequest()); WebSocket serverWebSocket = await context.AcceptWebSocketAsync(); WebSocket clientWebSocket = await clientTask;