#137 Relayer and ifdef WebSockets

Rename Microsoft.Net.WebSockets to Microsoft.Net.WebSockets.Server.
Reverse dependency with Microsoft.Net.Http.Server.
ifdef out IHttpWebSocketFeature.
This commit is contained in:
Chris R 2015-12-02 14:50:32 -08:00
parent 7a310a35db
commit fca0476936
34 changed files with 245 additions and 351 deletions

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22710.0
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "samples\TestClient\TestClient.csproj", "{8B828433-B333-4C19-96AE-00BFFF9D8841}"
EndProject
@ -17,7 +17,7 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HelloWorld", "samples\Hello
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SelfHostServer", "samples\SelfHostServer\SelfHostServer.xproj", "{1236F93A-AC5C-4A77-9477-C88F040151CA}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Net.WebSockets", "src\Microsoft.Net.WebSockets\Microsoft.Net.WebSockets.xproj", "{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}"
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Net.WebSockets.Server", "src\Microsoft.Net.WebSockets.Server\Microsoft.Net.WebSockets.Server.xproj", "{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Server.WebListener.FunctionalTests", "test\Microsoft.AspNet.Server.WebListener.FunctionalTests\Microsoft.AspNet.Server.WebListener.FunctionalTests.xproj", "{4492FF4C-9032-411D-853F-46B01755E504}"
EndProject

View File

@ -59,7 +59,7 @@ namespace HelloWorld
// Response
byte[] bytes = Encoding.ASCII.GetBytes("Hello World: " + DateTime.Now);
if (context.IsWebSocketRequest)
if (context.IsWebSocketRequest())
{
Console.WriteLine("WebSocket");
WebSocket webSocket = await context.AcceptWebSocketAsync();

View File

@ -1,6 +1,7 @@
{
"dependencies": {
"Microsoft.Net.Http.Server": "1.0.0-*"
"Microsoft.Net.Http.Server": "1.0.0-*",
"Microsoft.Net.WebSockets.Server": "1.0.0-*"
},
"commands": {
"sample": "HelloWorld"

View File

@ -16,7 +16,6 @@
// permissions and limitations under the License.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.WebSockets;
@ -27,8 +26,6 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Features.Authentication;
using Microsoft.AspNet.Http.Internal;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
using Microsoft.Net.Http.Server;
@ -43,7 +40,9 @@ namespace Microsoft.AspNet.Server.WebListener
ITlsTokenBindingFeature,
IHttpBufferingFeature,
IHttpRequestLifetimeFeature,
#if WEBSOCKETS
IHttpWebSocketFeature,
#endif
IHttpAuthenticationFeature,
IHttpUpgradeFeature,
IHttpRequestIdentifierFeature
@ -422,12 +421,12 @@ namespace Microsoft.AspNet.Server.WebListener
{
return _requestContext.UpgradeAsync();
}
#if WEBSOCKETS
bool IHttpWebSocketFeature.IsWebSocketRequest
{
get
{
return _requestContext.IsWebSocketRequest;
return _requestContext.IsWebSocketRequest();
}
}
@ -441,7 +440,7 @@ namespace Microsoft.AspNet.Server.WebListener
}
return _requestContext.AcceptWebSocketAsync(subProtocol);
}
#endif
ClaimsPrincipal IHttpAuthenticationFeature.User
{
get

View File

@ -24,14 +24,11 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Net.WebSockets;
namespace Microsoft.Net.Http.Server
{
@ -174,198 +171,6 @@ namespace Microsoft.Net.Http.Server
return Task.FromResult(opaqueStream);
}
public bool IsWebSocketRequest
{
get
{
if (!WebSocketHelpers.AreWebSocketsSupported)
{
return false;
}
if (!IsUpgradableRequest)
{
return false;
}
if (!string.Equals("GET", Request.Method, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Connection: Upgrade (some odd clients send Upgrade,KeepAlive)
string connection = Request.Headers[HttpKnownHeaderNames.Connection];
if (connection == null || connection.IndexOf(HttpKnownHeaderNames.Upgrade, StringComparison.OrdinalIgnoreCase) < 0)
{
return false;
}
// Upgrade: websocket
string upgrade = Request.Headers[HttpKnownHeaderNames.Upgrade];
if (!string.Equals(WebSocketHelpers.WebSocketUpgradeToken, upgrade, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Sec-WebSocket-Version: 13
string version = Request.Headers[HttpKnownHeaderNames.SecWebSocketVersion];
if (!string.Equals(WebSocketConstants.SupportedProtocolVersion, version, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Sec-WebSocket-Key: {base64string}
string key = Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
if (!WebSocketHelpers.IsValidWebSocketKey(key))
{
return false;
}
return true;
}
}
// Compare IsWebSocketRequest
private void ValidateWebSocketRequest()
{
if (!WebSocketHelpers.AreWebSocketsSupported)
{
throw new NotSupportedException("WebSockets are not supported on this platform.");
}
if (!IsUpgradableRequest)
{
throw new InvalidOperationException("This request is not a valid upgrade request.");
}
if (!string.Equals("GET", Request.Method, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("This request is not a valid upgrade request; invalid verb: " + Request.Method);
}
// Connection: Upgrade (some odd clients send Upgrade,KeepAlive)
string connection = Request.Headers[HttpKnownHeaderNames.Connection];
if (connection == null || connection.IndexOf(HttpKnownHeaderNames.Upgrade, StringComparison.OrdinalIgnoreCase) < 0)
{
throw new InvalidOperationException("The Connection header is invalid: " + connection);
}
// Upgrade: websocket
string upgrade = Request.Headers[HttpKnownHeaderNames.Upgrade];
if (!string.Equals(WebSocketHelpers.WebSocketUpgradeToken, upgrade, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The Upgrade header is invalid: " + upgrade);
}
// Sec-WebSocket-Version: 13
string version = Request.Headers[HttpKnownHeaderNames.SecWebSocketVersion];
if (!string.Equals(WebSocketConstants.SupportedProtocolVersion, version, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The Sec-WebSocket-Version header is invalid or not supported: " + version);
}
// Sec-WebSocket-Key: {base64string}
string key = Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
if (!WebSocketHelpers.IsValidWebSocketKey(key))
{
throw new InvalidOperationException("The Sec-WebSocket-Key header is invalid: " + upgrade);
}
}
public Task<WebSocket> AcceptWebSocketAsync()
{
return AcceptWebSocketAsync(null,
WebSocketHelpers.DefaultReceiveBufferSize,
WebSocketHelpers.DefaultKeepAliveInterval);
}
public Task<WebSocket> AcceptWebSocketAsync(string subProtocol)
{
return AcceptWebSocketAsync(subProtocol,
WebSocketHelpers.DefaultReceiveBufferSize,
WebSocketHelpers.DefaultKeepAliveInterval);
}
public Task<WebSocket> AcceptWebSocketAsync(string subProtocol, TimeSpan keepAliveInterval)
{
return AcceptWebSocketAsync(subProtocol,
WebSocketHelpers.DefaultReceiveBufferSize,
keepAliveInterval);
}
public Task<WebSocket> AcceptWebSocketAsync(
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval)
{
WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, keepAliveInterval);
ArraySegment<byte> internalBuffer = WebSocketBuffer.CreateInternalBufferArraySegment(receiveBufferSize, WebSocketBuffer.MinSendBufferSize, true);
return this.AcceptWebSocketAsync(subProtocol,
receiveBufferSize,
keepAliveInterval,
internalBuffer);
}
public Task<WebSocket> AcceptWebSocketAsync(
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval,
ArraySegment<byte> internalBuffer)
{
if (!IsUpgradableRequest)
{
throw new InvalidOperationException("This request is cannot be upgraded.");
}
WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, keepAliveInterval);
WebSocketHelpers.ValidateArraySegment<byte>(internalBuffer, "internalBuffer");
WebSocketBuffer.Validate(internalBuffer.Count, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, true);
return AcceptWebSocketAsyncCore(subProtocol, receiveBufferSize, keepAliveInterval, internalBuffer);
}
private async Task<WebSocket> AcceptWebSocketAsyncCore(
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval,
ArraySegment<byte> internalBuffer)
{
try
{
ValidateWebSocketRequest();
var subProtocols = Request.Headers.GetValues(HttpKnownHeaderNames.SecWebSocketProtocol);
bool shouldSendSecWebSocketProtocolHeader = WebSocketHelpers.ProcessWebSocketProtocolHeader(subProtocols, subProtocol);
if (shouldSendSecWebSocketProtocolHeader)
{
Response.Headers[HttpKnownHeaderNames.SecWebSocketProtocol] = subProtocol;
}
// negotiate the websocket key return value
string secWebSocketKey = Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
string secWebSocketAccept = WebSocketHelpers.GetSecWebSocketAcceptString(secWebSocketKey);
Response.Headers.Append(HttpKnownHeaderNames.Connection, HttpKnownHeaderNames.Upgrade);
Response.Headers.Append(HttpKnownHeaderNames.Upgrade, WebSocketHelpers.WebSocketUpgradeToken);
Response.Headers.Append(HttpKnownHeaderNames.SecWebSocketAccept, secWebSocketAccept);
Stream opaqueStream = await UpgradeAsync();
return WebSocketHelpers.CreateServerWebSocket(
opaqueStream,
subProtocol,
receiveBufferSize,
keepAliveInterval,
internalBuffer);
}
catch (Exception ex)
{
LogHelper.LogException(Logger, "AcceptWebSocketAsync", ex);
throw;
}
}
/*
public bool TryGetChannelBinding(ref ChannelBinding value)
{

View File

@ -3,8 +3,7 @@
"description": "Implementation of WebListener, a successor to HttpListener. It is used in the WebListener server package.",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "1.0.0-*",
"Microsoft.Extensions.Primitives": "1.0.0-*",
"Microsoft.Net.WebSockets": "1.0.0-*"
"Microsoft.Extensions.Primitives": "1.0.0-*"
},
"compilationOptions": {
"allowUnsafe": true,
@ -15,11 +14,16 @@
"dotnet5.4": {
"dependencies": {
"Microsoft.Win32.Primitives": "4.0.1-*",
"System.Diagnostics.Contracts": "4.0.1-*",
"System.Diagnostics.Debug": "4.0.11-*",
"System.Diagnostics.Tools": "4.0.1-*",
"System.IO": "4.0.11-*",
"System.IO.FileSystem": "4.0.1-*",
"System.Net.Primitives": "4.0.11-*",
"System.Security.Claims": "4.0.1-*",
"System.Security.Cryptography.X509Certificates": "4.0.0-*",
"System.Security.Principal.Windows": "4.0.0-*",
"System.Text.Encoding.Extensions": "4.0.11-*",
"System.Threading.Overlapped": "4.0.0-*"
}
}

View File

@ -23,7 +23,7 @@
namespace Microsoft.Net.WebSockets
{
public enum WebSocketError
internal enum WebSocketError
{
Success = 0,
InvalidMessageType = 1,

View File

@ -115,7 +115,7 @@ namespace Microsoft.Net.WebSockets
: base(message, innerException)
{
}
#if !DOTNET5_4
public override int ErrorCode
{
get
@ -123,7 +123,7 @@ namespace Microsoft.Net.WebSockets
return base.NativeErrorCode;
}
}
#endif
public WebSocketError WebSocketErrorCode
{
get

View File

@ -0,0 +1,217 @@
// Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing
// permissions and limitations under the License.
//------------------------------------------------------------------------------
// <copyright file="WebSocketHelpers.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.IO;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Microsoft.Net.WebSockets;
namespace Microsoft.Net.Http.Server
{
public static class WebSocketExtensions
{
public static bool IsWebSocketRequest(this RequestContext context)
{
if (!WebSocketHelpers.AreWebSocketsSupported)
{
return false;
}
if (!context.IsUpgradableRequest)
{
return false;
}
if (!string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Connection: Upgrade (some odd clients send Upgrade,KeepAlive)
string connection = context.Request.Headers[HttpKnownHeaderNames.Connection];
if (connection == null || connection.IndexOf(HttpKnownHeaderNames.Upgrade, StringComparison.OrdinalIgnoreCase) < 0)
{
return false;
}
// Upgrade: websocket
string upgrade = context.Request.Headers[HttpKnownHeaderNames.Upgrade];
if (!string.Equals(WebSocketHelpers.WebSocketUpgradeToken, upgrade, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Sec-WebSocket-Version: 13
string version = context.Request.Headers[HttpKnownHeaderNames.SecWebSocketVersion];
if (!string.Equals(WebSocketConstants.SupportedProtocolVersion, version, StringComparison.OrdinalIgnoreCase))
{
return false;
}
// Sec-WebSocket-Key: {base64string}
string key = context.Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
if (!WebSocketHelpers.IsValidWebSocketKey(key))
{
return false;
}
return true;
}
// Compare IsWebSocketRequest()
private static void ValidateWebSocketRequest(RequestContext context)
{
if (!WebSocketHelpers.AreWebSocketsSupported)
{
throw new NotSupportedException("WebSockets are not supported on this platform.");
}
if (!context.IsUpgradableRequest)
{
throw new InvalidOperationException("This request is not a valid upgrade request.");
}
if (!string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("This request is not a valid upgrade request; invalid verb: " + context.Request.Method);
}
// Connection: Upgrade (some odd clients send Upgrade,KeepAlive)
string connection = context.Request.Headers[HttpKnownHeaderNames.Connection];
if (connection == null || connection.IndexOf(HttpKnownHeaderNames.Upgrade, StringComparison.OrdinalIgnoreCase) < 0)
{
throw new InvalidOperationException("The Connection header is invalid: " + connection);
}
// Upgrade: websocket
string upgrade = context.Request.Headers[HttpKnownHeaderNames.Upgrade];
if (!string.Equals(WebSocketHelpers.WebSocketUpgradeToken, upgrade, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The Upgrade header is invalid: " + upgrade);
}
// Sec-WebSocket-Version: 13
string version = context.Request.Headers[HttpKnownHeaderNames.SecWebSocketVersion];
if (!string.Equals(WebSocketConstants.SupportedProtocolVersion, version, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The Sec-WebSocket-Version header is invalid or not supported: " + version);
}
// Sec-WebSocket-Key: {base64string}
string key = context.Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
if (!WebSocketHelpers.IsValidWebSocketKey(key))
{
throw new InvalidOperationException("The Sec-WebSocket-Key header is invalid: " + upgrade);
}
}
public static Task<WebSocket> AcceptWebSocketAsync(this RequestContext context)
{
return context.AcceptWebSocketAsync(null,
WebSocketHelpers.DefaultReceiveBufferSize,
WebSocketHelpers.DefaultKeepAliveInterval);
}
public static Task<WebSocket> AcceptWebSocketAsync(this RequestContext context, string subProtocol)
{
return context.AcceptWebSocketAsync(subProtocol,
WebSocketHelpers.DefaultReceiveBufferSize,
WebSocketHelpers.DefaultKeepAliveInterval);
}
public static Task<WebSocket> AcceptWebSocketAsync(this RequestContext context, string subProtocol, TimeSpan keepAliveInterval)
{
return context.AcceptWebSocketAsync(subProtocol,
WebSocketHelpers.DefaultReceiveBufferSize,
keepAliveInterval);
}
public static Task<WebSocket> AcceptWebSocketAsync(
this RequestContext context,
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval)
{
WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, keepAliveInterval);
ArraySegment<byte> internalBuffer = WebSocketBuffer.CreateInternalBufferArraySegment(receiveBufferSize, WebSocketBuffer.MinSendBufferSize, true);
return context.AcceptWebSocketAsync(subProtocol,
receiveBufferSize,
keepAliveInterval,
internalBuffer);
}
public static Task<WebSocket> AcceptWebSocketAsync(
this RequestContext context,
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval,
ArraySegment<byte> internalBuffer)
{
if (!context.IsUpgradableRequest)
{
throw new InvalidOperationException("This request is cannot be upgraded.");
}
WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, keepAliveInterval);
WebSocketHelpers.ValidateArraySegment<byte>(internalBuffer, "internalBuffer");
WebSocketBuffer.Validate(internalBuffer.Count, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, true);
return AcceptWebSocketAsyncCore(context, subProtocol, receiveBufferSize, keepAliveInterval, internalBuffer);
}
private static async Task<WebSocket> AcceptWebSocketAsyncCore(
RequestContext context,
string subProtocol,
int receiveBufferSize,
TimeSpan keepAliveInterval,
ArraySegment<byte> internalBuffer)
{
ValidateWebSocketRequest(context);
var subProtocols = context.Request.Headers.GetValues(HttpKnownHeaderNames.SecWebSocketProtocol);
bool shouldSendSecWebSocketProtocolHeader = WebSocketHelpers.ProcessWebSocketProtocolHeader(subProtocols, subProtocol);
if (shouldSendSecWebSocketProtocolHeader)
{
context.Response.Headers[HttpKnownHeaderNames.SecWebSocketProtocol] = subProtocol;
}
// negotiate the websocket key return value
string secWebSocketKey = context.Request.Headers[HttpKnownHeaderNames.SecWebSocketKey];
string secWebSocketAccept = WebSocketHelpers.GetSecWebSocketAcceptString(secWebSocketKey);
context.Response.Headers.Append(HttpKnownHeaderNames.Connection, HttpKnownHeaderNames.Upgrade);
context.Response.Headers.Append(HttpKnownHeaderNames.Upgrade, WebSocketHelpers.WebSocketUpgradeToken);
context.Response.Headers.Append(HttpKnownHeaderNames.SecWebSocketAccept, secWebSocketAccept);
Stream opaqueStream = await context.UpgradeAsync();
return WebSocketHelpers.CreateServerWebSocket(
opaqueStream,
subProtocol,
receiveBufferSize,
keepAliveInterval,
internalBuffer);
}
}
}

View File

@ -92,7 +92,6 @@ namespace Microsoft.Net.WebSockets
}
}
public static bool IsValidWebSocketKey(string key)
{
if (string.IsNullOrWhiteSpace(key))

View File

@ -27,7 +27,7 @@ using System.Net.WebSockets;
namespace Microsoft.Net.WebSockets
{
public static class WebSocketReceiveResultExtensions
internal static class WebSocketReceiveResultExtensions
{
internal static WebSocketReceiveResult DecrementAndClone(ref WebSocketReceiveResult original, int count)
{

View File

@ -1,7 +1,9 @@
{
"version": "1.0.0-*",
"description": "Implementation of WebSocket abstract base class. Used by WebListener.",
"dependencies": {},
"dependencies": {
"Microsoft.Net.Http.Server": "1.0.0-*"
},
"compilationOptions": {
"allowUnsafe": true,
"keyFile": "../../tools/Key.snk"
@ -11,16 +13,11 @@
"dotnet5.4": {
"dependencies": {
"System.Collections": "4.0.11-*",
"System.Diagnostics.Contracts": "4.0.1-*",
"System.Diagnostics.Tools": "4.0.1-*",
"System.IO": "4.0.11-*",
"System.Linq": "4.0.1-*",
"System.Net.Primitives": "4.0.11-*",
"System.Net.WebSockets": "4.0.0-*",
"System.Resources.ResourceManager": "4.0.1-*",
"System.Runtime.Extensions": "4.0.11-*",
"System.Security.Cryptography.Algorithms": "4.0.0-*",
"System.Text.Encoding.Extensions": "4.0.11-*",
"System.Threading": "4.0.11-*",
"System.Threading.Tasks": "4.0.11-*",
"System.Threading.Timer": "4.0.1-*",

View File

@ -1,129 +0,0 @@
// Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing
// permissions and limitations under the License.
//------------------------------------------------------------------------------
// <copyright file="HttpListenerException.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#if DOTNET5_4
using System.Runtime.InteropServices;
using System.Text;
namespace System.ComponentModel
{
internal class Win32Exception : ExternalException
{
/// <devdoc>
/// <para>Represents the Win32 error code associated with this exception. This
/// field is read-only.</para>
/// </devdoc>
private readonly int nativeErrorCode;
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the last Win32 error
/// that occured.</para>
/// </devdoc>
public Win32Exception()
: this(Marshal.GetLastWin32Error())
{
}
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error.</para>
/// </devdoc>
public Win32Exception(int error)
: this(error, GetErrorMessage(error))
{
}
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.ComponentModel.Win32Exception'/> class with the specified error and the
/// specified detailed description.</para>
/// </devdoc>
public Win32Exception(int error, string message)
: base(message)
{
nativeErrorCode = error;
}
/// <devdoc>
/// Initializes a new instance of the Exception class with a specified error message.
/// FxCop CA1032: Multiple constructors are required to correctly implement a custom exception.
/// </devdoc>
public Win32Exception(string message)
: this(Marshal.GetLastWin32Error(), message)
{
}
/// <devdoc>
/// Initializes a new instance of the Exception class with a specified error message and a
/// reference to the inner exception that is the cause of this exception.
/// FxCop CA1032: Multiple constructors are required to correctly implement a custom exception.
/// </devdoc>
public Win32Exception(string message, Exception innerException)
: base(message, innerException)
{
nativeErrorCode = Marshal.GetLastWin32Error();
}
/// <devdoc>
/// <para>Represents the Win32 error code associated with this exception. This
/// field is read-only.</para>
/// </devdoc>
public int NativeErrorCode
{
get
{
return nativeErrorCode;
}
}
private static string GetErrorMessage(int error)
{
//get the system error message...
string errorMsg = "";
StringBuilder sb = new StringBuilder(256);
int result = SafeNativeMethods.FormatMessage(
SafeNativeMethods.FORMAT_MESSAGE_IGNORE_INSERTS |
SafeNativeMethods.FORMAT_MESSAGE_FROM_SYSTEM |
SafeNativeMethods.FORMAT_MESSAGE_ARGUMENT_ARRAY,
IntPtr.Zero, (uint)error, 0, sb, sb.Capacity + 1,
null);
if (result != 0)
{
int i = sb.Length;
while (i > 0)
{
char ch = sb[i - 1];
if (ch > 32 && ch != '.') break;
i--;
}
errorMsg = sb.ToString(0, i);
}
else
{
errorMsg = "Unknown error (0x" + Convert.ToString(error, 16) + ")";
}
return errorMsg;
}
}
}
#endif

View File

@ -14,7 +14,7 @@
// NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing
// permissions and limitations under the License.
#if WEBSOCKETS
using System;
using System.Net.Http;
using System.Net.WebSockets;
@ -22,7 +22,6 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
@ -165,4 +164,5 @@ namespace Microsoft.AspNet.Server.WebListener
return client;
}
}
}
}
#endif

View File

@ -62,7 +62,7 @@ namespace Microsoft.Net.Http.Server
Task<WebSocket> clientTask = SendWebSocketRequestAsync(ConvertToWebSocketAddress(address));
var context = await server.GetContextAsync();
Assert.True(context.IsWebSocketRequest);
Assert.True(context.IsWebSocketRequest());
WebSocket serverWebSocket = await context.AcceptWebSocketAsync();
WebSocket clientWebSocket = await clientTask;

View File

@ -4,6 +4,7 @@
},
"dependencies": {
"Microsoft.Net.Http.Server": "1.0.0-*",
"Microsoft.Net.WebSockets.Server": "1.0.0-*",
"Microsoft.AspNet.Testing": "1.0.0-*",
"xunit.runner.aspnet": "2.0.0-aspnet-*"
},