Merge branch 'release/2.2'

This commit is contained in:
Stephen Halter 2018-11-08 15:17:48 -08:00
commit 9053772cd0
8 changed files with 60 additions and 60 deletions

View File

@ -11,42 +11,9 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
public partial class Http1Connection : IHttpUpgradeFeature, public partial class Http1Connection : IHttpMinRequestBodyDataRateFeature,
IHttpMinRequestBodyDataRateFeature,
IHttpMinResponseDataRateFeature IHttpMinResponseDataRateFeature
{ {
bool IHttpUpgradeFeature.IsUpgradableRequest => IsUpgradableRequest;
async Task<Stream> IHttpUpgradeFeature.UpgradeAsync()
{
if (!((IHttpUpgradeFeature)this).IsUpgradableRequest)
{
throw new InvalidOperationException(CoreStrings.CannotUpgradeNonUpgradableRequest);
}
if (IsUpgraded)
{
throw new InvalidOperationException(CoreStrings.UpgradeCannotBeCalledMultipleTimes);
}
if (!ServiceContext.ConnectionManager.UpgradedConnectionCount.TryLockOne())
{
throw new InvalidOperationException(CoreStrings.UpgradedConnectionLimitReached);
}
IsUpgraded = true;
ConnectionFeatures.Get<IDecrementConcurrentConnectionCountFeature>()?.ReleaseConnection();
StatusCode = StatusCodes.Status101SwitchingProtocols;
ReasonPhrase = "Switching Protocols";
ResponseHeaders["Connection"] = "Upgrade";
await FlushAsync(default(CancellationToken));
return _streams.Upgrade();
}
MinDataRate IHttpMinRequestBodyDataRateFeature.MinDataRate MinDataRate IHttpMinRequestBodyDataRateFeature.MinDataRate
{ {
get => MinRequestBodyDataRate; get => MinRequestBodyDataRate;

View File

@ -61,8 +61,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
public bool RequestTimedOut => _requestTimedOut; public bool RequestTimedOut => _requestTimedOut;
public override bool IsUpgradableRequest => _upgradeAvailable;
public MinDataRate MinRequestBodyDataRate { get; set; } public MinDataRate MinRequestBodyDataRate { get; set; }
public MinDataRate MinResponseDataRate { get; set; } public MinDataRate MinResponseDataRate { get; set; }

View File

@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
public partial class HttpProtocol : IHttpRequestFeature, public partial class HttpProtocol : IHttpRequestFeature,
IHttpResponseFeature, IHttpResponseFeature,
IHttpUpgradeFeature,
IHttpConnectionFeature, IHttpConnectionFeature,
IHttpRequestLifetimeFeature, IHttpRequestLifetimeFeature,
IHttpRequestIdentifierFeature, IHttpRequestIdentifierFeature,
@ -123,6 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
bool IHttpResponseFeature.HasStarted => HasResponseStarted; bool IHttpResponseFeature.HasStarted => HasResponseStarted;
bool IHttpUpgradeFeature.IsUpgradableRequest => IsUpgradableRequest;
IPAddress IHttpConnectionFeature.RemoteIpAddress IPAddress IHttpConnectionFeature.RemoteIpAddress
{ {
@ -192,7 +194,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
protected void ResetHttp1Features() protected void ResetHttp1Features()
{ {
_currentIHttpUpgradeFeature = this;
_currentIHttpMinRequestBodyDataRateFeature = this; _currentIHttpMinRequestBodyDataRateFeature = this;
_currentIHttpMinResponseDataRateFeature = this; _currentIHttpMinResponseDataRateFeature = this;
} }
@ -213,6 +214,36 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
OnCompleted(callback, state); OnCompleted(callback, state);
} }
async Task<Stream> IHttpUpgradeFeature.UpgradeAsync()
{
if (!IsUpgradableRequest)
{
throw new InvalidOperationException(CoreStrings.CannotUpgradeNonUpgradableRequest);
}
if (IsUpgraded)
{
throw new InvalidOperationException(CoreStrings.UpgradeCannotBeCalledMultipleTimes);
}
if (!ServiceContext.ConnectionManager.UpgradedConnectionCount.TryLockOne())
{
throw new InvalidOperationException(CoreStrings.UpgradedConnectionLimitReached);
}
IsUpgraded = true;
ConnectionFeatures.Get<IDecrementConcurrentConnectionCountFeature>()?.ReleaseConnection();
StatusCode = StatusCodes.Status101SwitchingProtocols;
ReasonPhrase = "Switching Protocols";
ResponseHeaders["Connection"] = "Upgrade";
await FlushAsync();
return _streams.Upgrade();
}
void IHttpRequestLifetimeFeature.Abort() void IHttpRequestLifetimeFeature.Abort()
{ {
ApplicationAbort(); ApplicationAbort();

View File

@ -67,6 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
_currentIHttpRequestFeature = this; _currentIHttpRequestFeature = this;
_currentIHttpResponseFeature = this; _currentIHttpResponseFeature = this;
_currentIHttpUpgradeFeature = this;
_currentIHttpRequestIdentifierFeature = this; _currentIHttpRequestIdentifierFeature = this;
_currentIHttpRequestLifetimeFeature = this; _currentIHttpRequestLifetimeFeature = this;
_currentIHttpConnectionFeature = this; _currentIHttpConnectionFeature = this;
@ -77,7 +78,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_currentIHttpAuthenticationFeature = null; _currentIHttpAuthenticationFeature = null;
_currentIQueryFeature = null; _currentIQueryFeature = null;
_currentIFormFeature = null; _currentIFormFeature = null;
_currentIHttpUpgradeFeature = null;
_currentIHttp2StreamIdFeature = null; _currentIHttp2StreamIdFeature = null;
_currentIHttpResponseTrailersFeature = null; _currentIHttpResponseTrailersFeature = null;
_currentIResponseCookiesFeature = null; _currentIResponseCookiesFeature = null;

View File

@ -50,7 +50,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// Keep-alive is default for HTTP/1.1 and HTTP/2; parsing and errors will change its value // Keep-alive is default for HTTP/1.1 and HTTP/2; parsing and errors will change its value
// volatile, see: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx // volatile, see: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
protected volatile bool _keepAlive = true; protected volatile bool _keepAlive = true;
protected bool _upgradeAvailable;
private bool _canHaveBody; private bool _canHaveBody;
private bool _autoChunk; private bool _autoChunk;
private Exception _applicationException; private Exception _applicationException;
@ -116,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
} }
public abstract bool IsUpgradableRequest { get; } public bool IsUpgradableRequest { get; private set; }
public bool IsUpgraded { get; set; } public bool IsUpgraded { get; set; }
public IPAddress RemoteIpAddress { get; set; } public IPAddress RemoteIpAddress { get; set; }
public int RemotePort { get; set; } public int RemotePort { get; set; }
@ -532,7 +531,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_keepAlive = false; _keepAlive = false;
} }
_upgradeAvailable = messageBody.RequestUpgrade; IsUpgradableRequest = messageBody.RequestUpgrade;
InitializeStreams(messageBody); InitializeStreams(messageBody);

View File

@ -68,8 +68,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
internal bool RstStreamReceived => (_completionState & StreamCompletionFlags.RstStreamReceived) == StreamCompletionFlags.RstStreamReceived; internal bool RstStreamReceived => (_completionState & StreamCompletionFlags.RstStreamReceived) == StreamCompletionFlags.RstStreamReceived;
internal bool IsDraining => (_completionState & StreamCompletionFlags.Draining) == StreamCompletionFlags.Draining; internal bool IsDraining => (_completionState & StreamCompletionFlags.Draining) == StreamCompletionFlags.Draining;
public override bool IsUpgradableRequest => false;
public bool ReceivedEmptyRequestBody public bool ReceivedEmptyRequestBody
{ {
get get

View File

@ -19,22 +19,30 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
public class HttpProtocolFeatureCollectionTests public class HttpProtocolFeatureCollectionTests
{ {
private readonly TestHttp1Connection _http1Connection; private readonly TestHttp1Connection _http1Connection;
private readonly HttpConnectionContext _http1ConnectionContext; private readonly HttpConnectionContext _httpConnectionContext;
private readonly IFeatureCollection _collection; private readonly IFeatureCollection _collection;
private readonly IFeatureCollection _http2Collection;
public HttpProtocolFeatureCollectionTests() public HttpProtocolFeatureCollectionTests()
{ {
_http1ConnectionContext = new HttpConnectionContext var context = new Http2StreamContext
{ {
ServiceContext = new TestServiceContext(), ServiceContext = new TestServiceContext(),
ConnectionFeatures = new FeatureCollection(), ConnectionFeatures = new FeatureCollection(),
TimeoutControl = Mock.Of<ITimeoutControl>(), TimeoutControl = Mock.Of<ITimeoutControl>(),
Transport = Mock.Of<IDuplexPipe>(), Transport = Mock.Of<IDuplexPipe>(),
ServerPeerSettings = new Http2PeerSettings(),
ClientPeerSettings = new Http2PeerSettings(),
}; };
_http1Connection = new TestHttp1Connection(_http1ConnectionContext); _httpConnectionContext = context;
_http1Connection = new TestHttp1Connection(context);
_http1Connection.Reset(); _http1Connection.Reset();
_collection = _http1Connection; _collection = _http1Connection;
var http2Stream = new Http2Stream(context);
http2Stream.Reset();
_http2Collection = http2Stream;
} }
[Fact] [Fact]
@ -143,24 +151,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
[Fact] [Fact]
public void Http2StreamFeatureCollectionDoesNotIncludeMinRateFeatures() public void Http2StreamFeatureCollectionDoesNotIncludeMinRateFeatures()
{ {
var http2Stream = new Http2Stream(new Http2StreamContext Assert.Null(_http2Collection.Get<IHttpMinRequestBodyDataRateFeature>());
{ Assert.Null(_http2Collection.Get<IHttpMinResponseDataRateFeature>());
ServiceContext = new TestServiceContext(),
ConnectionFeatures = new FeatureCollection(),
TimeoutControl = Mock.Of<ITimeoutControl>(),
Transport = Mock.Of<IDuplexPipe>(),
ServerPeerSettings = new Http2PeerSettings(),
ClientPeerSettings = new Http2PeerSettings(),
});
var http2StreamCollection = (IFeatureCollection)http2Stream;
Assert.Null(http2StreamCollection.Get<IHttpMinRequestBodyDataRateFeature>());
Assert.Null(http2StreamCollection.Get<IHttpMinResponseDataRateFeature>());
Assert.NotNull(_collection.Get<IHttpMinRequestBodyDataRateFeature>()); Assert.NotNull(_collection.Get<IHttpMinRequestBodyDataRateFeature>());
Assert.NotNull(_collection.Get<IHttpMinResponseDataRateFeature>()); Assert.NotNull(_collection.Get<IHttpMinResponseDataRateFeature>());
} }
[Fact]
public void Http2StreamFeatureCollectionDoesIncludeUpgradeFeature()
{
var upgradeFeature = _http2Collection.Get<IHttpUpgradeFeature>();
Assert.NotNull(upgradeFeature);
Assert.False(upgradeFeature.IsUpgradableRequest);
}
private void CompareGenericGetterToIndexer() private void CompareGenericGetterToIndexer()
{ {
Assert.Same(_collection.Get<IHttpRequestFeature>(), _collection[typeof(IHttpRequestFeature)]); Assert.Same(_collection.Get<IHttpRequestFeature>(), _collection[typeof(IHttpRequestFeature)]);
@ -213,6 +219,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
return featureCount; return featureCount;
} }
private Http1Connection CreateHttp1Connection() => new TestHttp1Connection(_http1ConnectionContext); private Http1Connection CreateHttp1Connection() => new TestHttp1Connection(_httpConnectionContext);
} }
} }

View File

@ -59,6 +59,7 @@ namespace CodeGenerator
{ {
"IHttpRequestFeature", "IHttpRequestFeature",
"IHttpResponseFeature", "IHttpResponseFeature",
"IHttpUpgradeFeature",
"IHttpRequestIdentifierFeature", "IHttpRequestIdentifierFeature",
"IHttpRequestLifetimeFeature", "IHttpRequestLifetimeFeature",
"IHttpConnectionFeature", "IHttpConnectionFeature",