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
{
public partial class Http1Connection : IHttpUpgradeFeature,
IHttpMinRequestBodyDataRateFeature,
public partial class Http1Connection : IHttpMinRequestBodyDataRateFeature,
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
{
get => MinRequestBodyDataRate;

View File

@ -61,8 +61,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
public bool RequestTimedOut => _requestTimedOut;
public override bool IsUpgradableRequest => _upgradeAvailable;
public MinDataRate MinRequestBodyDataRate { 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,
IHttpResponseFeature,
IHttpUpgradeFeature,
IHttpConnectionFeature,
IHttpRequestLifetimeFeature,
IHttpRequestIdentifierFeature,
@ -123,6 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
bool IHttpResponseFeature.HasStarted => HasResponseStarted;
bool IHttpUpgradeFeature.IsUpgradableRequest => IsUpgradableRequest;
IPAddress IHttpConnectionFeature.RemoteIpAddress
{
@ -192,7 +194,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
protected void ResetHttp1Features()
{
_currentIHttpUpgradeFeature = this;
_currentIHttpMinRequestBodyDataRateFeature = this;
_currentIHttpMinResponseDataRateFeature = this;
}
@ -213,6 +214,36 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
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()
{
ApplicationAbort();

View File

@ -67,6 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
_currentIHttpRequestFeature = this;
_currentIHttpResponseFeature = this;
_currentIHttpUpgradeFeature = this;
_currentIHttpRequestIdentifierFeature = this;
_currentIHttpRequestLifetimeFeature = this;
_currentIHttpConnectionFeature = this;
@ -77,7 +78,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_currentIHttpAuthenticationFeature = null;
_currentIQueryFeature = null;
_currentIFormFeature = null;
_currentIHttpUpgradeFeature = null;
_currentIHttp2StreamIdFeature = null;
_currentIHttpResponseTrailersFeature = 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
// volatile, see: https://msdn.microsoft.com/en-us/library/x13ttww7.aspx
protected volatile bool _keepAlive = true;
protected bool _upgradeAvailable;
private bool _canHaveBody;
private bool _autoChunk;
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 IPAddress RemoteIpAddress { get; set; }
public int RemotePort { get; set; }
@ -532,7 +531,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_keepAlive = false;
}
_upgradeAvailable = messageBody.RequestUpgrade;
IsUpgradableRequest = messageBody.RequestUpgrade;
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 IsDraining => (_completionState & StreamCompletionFlags.Draining) == StreamCompletionFlags.Draining;
public override bool IsUpgradableRequest => false;
public bool ReceivedEmptyRequestBody
{
get

View File

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

View File

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