Exclude the upgrade feature if the OS does not support it #427
This commit is contained in:
parent
336e85d19a
commit
dbd557c965
|
|
@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
// { typeof(ITlsTokenBindingFeature), ctx => ctx.GetTlsTokenBindingFeature() }, TODO: https://github.com/aspnet/HttpSysServer/issues/231
|
||||
{ typeof(IHttpBufferingFeature), _identityFunc },
|
||||
{ typeof(IHttpRequestLifetimeFeature), _identityFunc },
|
||||
{ typeof(IHttpUpgradeFeature), _identityFunc },
|
||||
{ typeof(IHttpAuthenticationFeature), _identityFunc },
|
||||
{ typeof(IHttpRequestIdentifierFeature), _identityFunc },
|
||||
{ typeof(RequestContext), ctx => ctx.RequestContext },
|
||||
|
|
@ -32,6 +31,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
|
||||
private readonly FeatureContext _featureContext;
|
||||
|
||||
static StandardFeatureCollection()
|
||||
{
|
||||
if (ComNetOS.IsWin8orLater)
|
||||
{
|
||||
// Only add the upgrade feature if it stands a chance of working.
|
||||
// SignalR uses the presence of the feature to detect feature support.
|
||||
// https://github.com/aspnet/HttpSysServer/issues/427
|
||||
_featureFuncLookup[typeof(IHttpUpgradeFeature)] = _identityFunc;
|
||||
}
|
||||
}
|
||||
|
||||
public StandardFeatureCollection(FeatureContext featureContext)
|
||||
{
|
||||
_featureContext = featureContext;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Testing.xunit
|
||||
{
|
||||
// Skip except on a specific OS and version
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
public class OSDontSkipConditionAttribute : Attribute, ITestCondition
|
||||
{
|
||||
private readonly OperatingSystems _includedOperatingSystem;
|
||||
private readonly IEnumerable<string> _includedVersions;
|
||||
private readonly OperatingSystems _osPlatform;
|
||||
private readonly string _osVersion;
|
||||
|
||||
public OSDontSkipConditionAttribute(OperatingSystems operatingSystem, params string[] versions) :
|
||||
this(
|
||||
operatingSystem,
|
||||
GetCurrentOS(),
|
||||
GetCurrentOSVersion(),
|
||||
versions)
|
||||
{
|
||||
}
|
||||
|
||||
// to enable unit testing
|
||||
internal OSDontSkipConditionAttribute(
|
||||
OperatingSystems operatingSystem, OperatingSystems osPlatform, string osVersion, params string[] versions)
|
||||
{
|
||||
_includedOperatingSystem = operatingSystem;
|
||||
_includedVersions = versions ?? Enumerable.Empty<string>();
|
||||
_osPlatform = osPlatform;
|
||||
_osVersion = osVersion;
|
||||
}
|
||||
|
||||
public bool IsMet
|
||||
{
|
||||
get
|
||||
{
|
||||
var currentOSInfo = new OSInfo()
|
||||
{
|
||||
OperatingSystem = _osPlatform,
|
||||
Version = _osVersion,
|
||||
};
|
||||
|
||||
var skip = (_includedOperatingSystem & currentOSInfo.OperatingSystem) != currentOSInfo.OperatingSystem;
|
||||
if (!skip && _includedVersions.Any())
|
||||
{
|
||||
skip = !_includedVersions.Any(inc => _osVersion.StartsWith(inc, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
// Since a test would be excuted only if 'IsMet' is true, return false if we want to skip
|
||||
return !skip;
|
||||
}
|
||||
}
|
||||
|
||||
public string SkipReason { get; set; } = "Test cannot run on this operating system.";
|
||||
|
||||
static private OperatingSystems GetCurrentOS()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return OperatingSystems.Windows;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return OperatingSystems.Linux;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return OperatingSystems.MacOSX;
|
||||
}
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
static private string GetCurrentOSVersion()
|
||||
{
|
||||
// currently not used on other OS's
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return Environment.OSVersion.Version.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private class OSInfo
|
||||
{
|
||||
public OperatingSystems OperatingSystem { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,32 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
{
|
||||
public class OpaqueUpgradeTests
|
||||
{
|
||||
[ConditionalFact]
|
||||
[OSDontSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_DownLevel_FeatureIsAbsent()
|
||||
{
|
||||
using (Utilities.CreateHttpServer(out var address, httpContext =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var opaqueFeature = httpContext.Features.Get<IHttpUpgradeFeature>();
|
||||
Assert.Null(opaqueFeature);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return httpContext.Response.WriteAsync(ex.ToString());
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
}))
|
||||
{
|
||||
HttpResponseMessage response = await SendRequestAsync(address);
|
||||
Assert.Equal(200, (int)response.StatusCode);
|
||||
Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked");
|
||||
Assert.Equal(0, response.Content.Headers.ContentLength);
|
||||
Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
|
||||
public async Task OpaqueUpgrade_SupportKeys_Present()
|
||||
|
|
|
|||
Loading…
Reference in New Issue