HttpSysServer 299 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. commit dbd557c9657f144c327b6e56f5289685a83c33ee
  2. Author: Chris Ross (ASP.NET) <[email protected]>
  3. Date: Tue Mar 6 20:25:51 2018 -0800
  4. Exclude the upgrade feature if the OS does not support it #427
  5. diff --git a/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs b/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
  6. index 0830de0fecb..2adf51d1fc4 100644
  7. --- a/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
  8. +++ b/src/Microsoft.AspNetCore.Server.HttpSys/StandardFeatureCollection.cs
  9. @@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
  10. // { typeof(ITlsTokenBindingFeature), ctx => ctx.GetTlsTokenBindingFeature() }, TODO: https://github.com/aspnet/HttpSysServer/issues/231
  11. { typeof(IHttpBufferingFeature), _identityFunc },
  12. { typeof(IHttpRequestLifetimeFeature), _identityFunc },
  13. - { typeof(IHttpUpgradeFeature), _identityFunc },
  14. { typeof(IHttpAuthenticationFeature), _identityFunc },
  15. { typeof(IHttpRequestIdentifierFeature), _identityFunc },
  16. { typeof(RequestContext), ctx => ctx.RequestContext },
  17. @@ -32,6 +31,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys
  18. private readonly FeatureContext _featureContext;
  19. + static StandardFeatureCollection()
  20. + {
  21. + if (ComNetOS.IsWin8orLater)
  22. + {
  23. + // Only add the upgrade feature if it stands a chance of working.
  24. + // SignalR uses the presence of the feature to detect feature support.
  25. + // https://github.com/aspnet/HttpSysServer/issues/427
  26. + _featureFuncLookup[typeof(IHttpUpgradeFeature)] = _identityFunc;
  27. + }
  28. + }
  29. +
  30. public StandardFeatureCollection(FeatureContext featureContext)
  31. {
  32. _featureContext = featureContext;
  33. diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OSDontSkipConditionAttribute.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OSDontSkipConditionAttribute.cs
  34. new file mode 100644
  35. index 00000000000..c657240a3ee
  36. --- /dev/null
  37. +++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OSDontSkipConditionAttribute.cs
  38. @@ -0,0 +1,99 @@
  39. +// Copyright (c) .NET Foundation. All rights reserved.
  40. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  41. +
  42. +using System;
  43. +using System.Collections.Generic;
  44. +using System.Linq;
  45. +using System.Runtime.InteropServices;
  46. +
  47. +namespace Microsoft.AspNetCore.Testing.xunit
  48. +{
  49. + // Skip except on a specific OS and version
  50. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
  51. + public class OSDontSkipConditionAttribute : Attribute, ITestCondition
  52. + {
  53. + private readonly OperatingSystems _includedOperatingSystem;
  54. + private readonly IEnumerable<string> _includedVersions;
  55. + private readonly OperatingSystems _osPlatform;
  56. + private readonly string _osVersion;
  57. +
  58. + public OSDontSkipConditionAttribute(OperatingSystems operatingSystem, params string[] versions) :
  59. + this(
  60. + operatingSystem,
  61. + GetCurrentOS(),
  62. + GetCurrentOSVersion(),
  63. + versions)
  64. + {
  65. + }
  66. +
  67. + // to enable unit testing
  68. + internal OSDontSkipConditionAttribute(
  69. + OperatingSystems operatingSystem, OperatingSystems osPlatform, string osVersion, params string[] versions)
  70. + {
  71. + _includedOperatingSystem = operatingSystem;
  72. + _includedVersions = versions ?? Enumerable.Empty<string>();
  73. + _osPlatform = osPlatform;
  74. + _osVersion = osVersion;
  75. + }
  76. +
  77. + public bool IsMet
  78. + {
  79. + get
  80. + {
  81. + var currentOSInfo = new OSInfo()
  82. + {
  83. + OperatingSystem = _osPlatform,
  84. + Version = _osVersion,
  85. + };
  86. +
  87. + var skip = (_includedOperatingSystem & currentOSInfo.OperatingSystem) != currentOSInfo.OperatingSystem;
  88. + if (!skip && _includedVersions.Any())
  89. + {
  90. + skip = !_includedVersions.Any(inc => _osVersion.StartsWith(inc, StringComparison.OrdinalIgnoreCase));
  91. + }
  92. +
  93. + // Since a test would be excuted only if 'IsMet' is true, return false if we want to skip
  94. + return !skip;
  95. + }
  96. + }
  97. +
  98. + public string SkipReason { get; set; } = "Test cannot run on this operating system.";
  99. +
  100. + static private OperatingSystems GetCurrentOS()
  101. + {
  102. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  103. + {
  104. + return OperatingSystems.Windows;
  105. + }
  106. + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
  107. + {
  108. + return OperatingSystems.Linux;
  109. + }
  110. + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
  111. + {
  112. + return OperatingSystems.MacOSX;
  113. + }
  114. + throw new PlatformNotSupportedException();
  115. + }
  116. +
  117. + static private string GetCurrentOSVersion()
  118. + {
  119. + // currently not used on other OS's
  120. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  121. + {
  122. + return Environment.OSVersion.Version.ToString();
  123. + }
  124. + else
  125. + {
  126. + return string.Empty;
  127. + }
  128. + }
  129. +
  130. + private class OSInfo
  131. + {
  132. + public OperatingSystems OperatingSystem { get; set; }
  133. +
  134. + public string Version { get; set; }
  135. + }
  136. + }
  137. +}
  138. \ No newline at end of file
  139. diff --git a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
  140. index c0fdda0dd28..609bc59fdda 100644
  141. --- a/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
  142. +++ b/test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/OpaqueUpgradeTests.cs
  143. @@ -17,6 +17,32 @@ namespace Microsoft.AspNetCore.Server.HttpSys
  144. {
  145. public class OpaqueUpgradeTests
  146. {
  147. + [ConditionalFact]
  148. + [OSDontSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
  149. + public async Task OpaqueUpgrade_DownLevel_FeatureIsAbsent()
  150. + {
  151. + using (Utilities.CreateHttpServer(out var address, httpContext =>
  152. + {
  153. + try
  154. + {
  155. + var opaqueFeature = httpContext.Features.Get<IHttpUpgradeFeature>();
  156. + Assert.Null(opaqueFeature);
  157. + }
  158. + catch (Exception ex)
  159. + {
  160. + return httpContext.Response.WriteAsync(ex.ToString());
  161. + }
  162. + return Task.FromResult(0);
  163. + }))
  164. + {
  165. + HttpResponseMessage response = await SendRequestAsync(address);
  166. + Assert.Equal(200, (int)response.StatusCode);
  167. + Assert.False(response.Headers.TransferEncodingChunked.HasValue, "Chunked");
  168. + Assert.Equal(0, response.Content.Headers.ContentLength);
  169. + Assert.Equal(string.Empty, await response.Content.ReadAsStringAsync());
  170. + }
  171. + }
  172. +
  173. [ConditionalFact]
  174. [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)]
  175. public async Task OpaqueUpgrade_SupportKeys_Present()