Enable WebSocket and Opaque features.

This commit is contained in:
Chris Ross 2014-06-12 15:04:56 -07:00
parent ae6004dd11
commit b9d7561bf9
13 changed files with 120 additions and 9 deletions

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.WebSockets;
using System.Security.Claims; using System.Security.Claims;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -27,6 +28,10 @@ namespace Microsoft.AspNet.Http
public abstract CancellationToken OnRequestAborted { get; } public abstract CancellationToken OnRequestAborted { get; }
public abstract bool IsWebSocketRequest { get; }
public abstract IList<string> WebSocketRequestedProtocols { get; }
public abstract void Abort(); public abstract void Abort();
public abstract void Dispose(); public abstract void Dispose();
@ -60,5 +65,12 @@ namespace Microsoft.AspNet.Http
} }
public abstract Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes); public abstract Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes);
public virtual Task<WebSocket> AcceptWebSocketAsync()
{
return AcceptWebSocket(subProtocol: null);
}
public abstract Task<WebSocket> AcceptWebSocket(string subProtocol);
} }
} }

View File

@ -5,6 +5,7 @@
"net45": {}, "net45": {},
"k10": { "k10": {
"dependencies": { "dependencies": {
"Microsoft.Net.WebSocketAbstractions": "0.1-alpha-*",
"System.Collections": "4.0.0.0", "System.Collections": "4.0.0.0",
"System.ComponentModel": "4.0.0.0", "System.ComponentModel": "4.0.0.0",
"System.Diagnostics.Tools": "4.0.0.0", "System.Diagnostics.Tools": "4.0.0.0",

View File

@ -0,0 +1,13 @@
using System.IO;
using System.Threading.Tasks;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.HttpFeature
{
[AssemblyNeutral]
public interface IHttpOpaqueUpgradeFeature
{
bool IsUpgradableRequest { get; }
Task<Stream> UpgradeAsync();
}
}

View File

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if NET45
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Framework.Runtime; using Microsoft.Framework.Runtime;
@ -11,8 +10,8 @@ namespace Microsoft.AspNet.HttpFeature
[AssemblyNeutral] [AssemblyNeutral]
public interface IHttpWebSocketFeature public interface IHttpWebSocketFeature
{ {
bool IsWebSocketRequest { get; set; } bool IsWebSocketRequest { get; }
Task<WebSocket> AcceptAsync();
Task<WebSocket> AcceptAsync(IWebSocketAcceptContext context);
} }
} }
#endif

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.HttpFeature
{
[AssemblyNeutral]
public interface IWebSocketAcceptContext
{
string SubProtocol { get; set; }
}
}

View File

@ -24,12 +24,14 @@
<Compile Include="IHttpApplicationFeature.cs" /> <Compile Include="IHttpApplicationFeature.cs" />
<Compile Include="IHttpBufferingFeature.cs" /> <Compile Include="IHttpBufferingFeature.cs" />
<Compile Include="IHttpConnectionFeature.cs" /> <Compile Include="IHttpConnectionFeature.cs" />
<Compile Include="IHttpOpaqueUpgradeFeature.cs" />
<Compile Include="IHttpRequestFeature.cs" /> <Compile Include="IHttpRequestFeature.cs" />
<Compile Include="IHttpRequestLifetimeFeature.cs" /> <Compile Include="IHttpRequestLifetimeFeature.cs" />
<Compile Include="IHttpResponseFeature.cs" /> <Compile Include="IHttpResponseFeature.cs" />
<Compile Include="IHttpSendFileFeature.cs" /> <Compile Include="IHttpSendFileFeature.cs" />
<Compile Include="IHttpTransportLayerSecurityFeature.cs" /> <Compile Include="IHttpTransportLayerSecurityFeature.cs" />
<Compile Include="IHttpWebSocketFeature.cs" /> <Compile Include="IHttpWebSocketFeature.cs" />
<Compile Include="IWebSocketAcceptContext.cs" />
<Compile Include="Security\IAuthenticateContext.cs" /> <Compile Include="Security\IAuthenticateContext.cs" />
<Compile Include="Security\IAuthenticationHandler.cs" /> <Compile Include="Security\IAuthenticationHandler.cs" />
<Compile Include="Security\IAuthTypeContext.cs" /> <Compile Include="Security\IAuthTypeContext.cs" />

View File

@ -4,6 +4,7 @@
"net45": {}, "net45": {},
"k10": { "k10": {
"dependencies": { "dependencies": {
"Microsoft.Net.WebSocketAbstractions": "0.1-alpha-*",
"System.IO": "4.0.0.0", "System.IO": "4.0.0.0",
"System.Net.Primitives": "4.0.10.0", "System.Net.Primitives": "4.0.10.0",
"System.Runtime": "4.0.20.0", "System.Runtime": "4.0.20.0",

View File

@ -4,12 +4,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.WebSockets;
using System.Security.Claims; using System.Security.Claims;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.FeatureModel; using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Infrastructure;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.HttpFeature; using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security; using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.PipelineCore.Infrastructure; using Microsoft.AspNet.PipelineCore.Infrastructure;
@ -19,6 +21,8 @@ namespace Microsoft.AspNet.PipelineCore
{ {
public class DefaultHttpContext : HttpContext public class DefaultHttpContext : HttpContext
{ {
private static IList<string> EmptyList = new List<string>();
private readonly HttpRequest _request; private readonly HttpRequest _request;
private readonly HttpResponse _response; private readonly HttpResponse _response;
@ -26,6 +30,7 @@ namespace Microsoft.AspNet.PipelineCore
private FeatureReference<IServiceProvidersFeature> _serviceProviders; private FeatureReference<IServiceProvidersFeature> _serviceProviders;
private FeatureReference<IHttpAuthenticationFeature> _authentication; private FeatureReference<IHttpAuthenticationFeature> _authentication;
private FeatureReference<IHttpRequestLifetimeFeature> _lifetime; private FeatureReference<IHttpRequestLifetimeFeature> _lifetime;
private FeatureReference<IHttpWebSocketFeature> _webSockets;
private IFeatureCollection _features; private IFeatureCollection _features;
public DefaultHttpContext(IFeatureCollection features) public DefaultHttpContext(IFeatureCollection features)
@ -37,6 +42,8 @@ namespace Microsoft.AspNet.PipelineCore
_items = FeatureReference<IItemsFeature>.Default; _items = FeatureReference<IItemsFeature>.Default;
_serviceProviders = FeatureReference<IServiceProvidersFeature>.Default; _serviceProviders = FeatureReference<IServiceProvidersFeature>.Default;
_authentication = FeatureReference<IHttpAuthenticationFeature>.Default; _authentication = FeatureReference<IHttpAuthenticationFeature>.Default;
_lifetime = FeatureReference<IHttpRequestLifetimeFeature>.Default;
_webSockets = FeatureReference<IHttpWebSocketFeature>.Default;
} }
IItemsFeature ItemsFeature IItemsFeature ItemsFeature
@ -59,6 +66,11 @@ namespace Microsoft.AspNet.PipelineCore
get { return _lifetime.Fetch(_features); } get { return _lifetime.Fetch(_features); }
} }
private IHttpWebSocketFeature WebSocketFeature
{
get { return _webSockets.Fetch(_features); }
}
public override HttpRequest Request { get { return _request; } } public override HttpRequest Request { get { return _request; } }
public override HttpResponse Response { get { return _response; } } public override HttpResponse Response { get { return _response; } }
@ -110,6 +122,23 @@ namespace Microsoft.AspNet.PipelineCore
} }
} }
public override bool IsWebSocketRequest
{
get
{
var webSocketFeature = WebSocketFeature;
return webSocketFeature != null && webSocketFeature.IsWebSocketRequest;
}
}
public override IList<string> WebSocketRequestedProtocols
{
get
{
return Request.Headers.GetValues(Constants.Headers.WebSocketSubProtocols) ?? EmptyList;
}
}
public override void Abort() public override void Abort()
{ {
var lifetime = LifetimeFeature; var lifetime = LifetimeFeature;
@ -196,5 +225,15 @@ namespace Microsoft.AspNet.PipelineCore
return authenticateContext.Results; return authenticateContext.Results;
} }
public override Task<WebSocket> AcceptWebSocket(string subProtocol)
{
var webSocketFeature = WebSocketFeature;
if (WebSocketFeature == null)
{
throw new NotSupportedException("WebSockets are not supported");
}
return WebSocketFeature.AcceptAsync(new WebSocketAcceptContext() { SubProtocol = subProtocol } );
}
} }
} }

View File

@ -22,6 +22,7 @@ namespace Microsoft.AspNet.Http.Infrastructure
internal const string Cookie = "Cookie"; internal const string Cookie = "Cookie";
internal const string SetCookie = "Set-Cookie"; internal const string SetCookie = "Set-Cookie";
internal const string Expires = "Expires"; internal const string Expires = "Expires";
internal const string WebSocketSubProtocols = "Sec-WebSocket-Protocol";
} }
} }
} }

View File

@ -51,6 +51,7 @@
<Compile Include="Security\HttpAuthenticationFeature.cs" /> <Compile Include="Security\HttpAuthenticationFeature.cs" />
<Compile Include="Security\SignInContext.cs" /> <Compile Include="Security\SignInContext.cs" />
<Compile Include="Security\SignOutContext.cs" /> <Compile Include="Security\SignOutContext.cs" />
<Compile Include="WebSocketAcceptContext.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.HttpFeature;
namespace Microsoft.AspNet.PipelineCore
{
public class WebSocketAcceptContext : IWebSocketAcceptContext
{
public virtual string SubProtocol { get; set; }
}
}

View File

@ -10,6 +10,7 @@
"net45": {}, "net45": {},
"k10": { "k10": {
"dependencies": { "dependencies": {
"Microsoft.Net.WebSocketAbstractions": "0.1-alpha-*",
"System.Collections": "4.0.0.0", "System.Collections": "4.0.0.0",
"System.ComponentModel": "4.0.0.0", "System.ComponentModel": "4.0.0.0",
"System.Diagnostics.Debug": "4.0.10.0", "System.Diagnostics.Debug": "4.0.10.0",

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.WebSockets;
using System.Security.Claims; using System.Security.Claims;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -113,10 +114,25 @@ namespace Microsoft.AspNet.Owin
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public override bool IsWebSocketRequest
{
get { throw new NotImplementedException(); }
}
public override IList<string> WebSocketRequestedProtocols
{
get { throw new NotImplementedException(); }
}
public override void Abort() public override void Abort()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override Task<WebSocket> AcceptWebSocket(string subProtocol)
{
throw new NotImplementedException();
}
} }
private class MoqHttpRequest : HttpRequest, IHttpRequestFeature private class MoqHttpRequest : HttpRequest, IHttpRequestFeature