BasicMiddleware 744 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. commit fd4cd6f58b2412d4ca6e264803356af5fc474e5a
  2. Author: Justin Kotalik <[email protected]>
  3. Date: Tue Dec 19 22:44:24 2017 -0800
  4. Read from IServerAddressesFeature for HTTPS port (#276)
  5. diff --git a/build/dependencies.props b/build/dependencies.props
  6. index 229023f5d03..853f6f2f0e6 100644
  7. --- a/build/dependencies.props
  8. +++ b/build/dependencies.props
  9. @@ -3,23 +3,25 @@
  10. <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
  11. </PropertyGroup>
  12. <PropertyGroup Label="Package Versions">
  13. - <InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15626</InternalAspNetCoreSdkPackageVersion>
  14. - <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
  15. - <MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
  16. - <MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
  17. - <MicrosoftAspNetCoreHttpPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreHttpPackageVersion>
  18. - <MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
  19. - <MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreServerKestrelPackageVersion>
  20. - <MicrosoftAspNetCoreTestHostPackageVersion>2.1.0-preview1-27849</MicrosoftAspNetCoreTestHostPackageVersion>
  21. - <MicrosoftExtensionsConfigurationAbstractionsPackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
  22. - <MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
  23. - <MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
  24. - <MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsLoggingConsolePackageVersion>
  25. - <MicrosoftExtensionsLoggingTestingPackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsLoggingTestingPackageVersion>
  26. - <MicrosoftExtensionsOptionsPackageVersion>2.1.0-preview1-27849</MicrosoftExtensionsOptionsPackageVersion>
  27. + <InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15638</InternalAspNetCoreSdkPackageVersion>
  28. + <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
  29. + <MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
  30. + <MicrosoftAspNetCoreHttpExtensionsPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
  31. + <MicrosoftAspNetCoreHttpPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreHttpPackageVersion>
  32. + <MicrosoftAspNetCoreServerKestrelCorePackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreServerKestrelCorePackageVersion>
  33. + <MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
  34. + <MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreServerKestrelPackageVersion>
  35. + <MicrosoftAspNetCoreTestHostPackageVersion>2.1.0-preview1-27855</MicrosoftAspNetCoreTestHostPackageVersion>
  36. + <MicrosoftExtensionsConfigurationAbstractionsPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
  37. + <MicrosoftExtensionsConfigurationBinderPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsConfigurationBinderPackageVersion>
  38. + <MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
  39. + <MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
  40. + <MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsLoggingConsolePackageVersion>
  41. + <MicrosoftExtensionsLoggingTestingPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsLoggingTestingPackageVersion>
  42. + <MicrosoftExtensionsOptionsPackageVersion>2.1.0-preview1-27855</MicrosoftExtensionsOptionsPackageVersion>
  43. <MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
  44. <MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-26016-05</MicrosoftNETCoreApp21PackageVersion>
  45. - <MicrosoftNetHttpHeadersPackageVersion>2.1.0-preview1-27849</MicrosoftNetHttpHeadersPackageVersion>
  46. + <MicrosoftNetHttpHeadersPackageVersion>2.1.0-preview1-27855</MicrosoftNetHttpHeadersPackageVersion>
  47. <MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
  48. <MoqPackageVersion>4.7.49</MoqPackageVersion>
  49. <XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
  50. diff --git a/korebuild-lock.txt b/korebuild-lock.txt
  51. index 8d52a6128cc..2e540bdffd1 100644
  52. --- a/korebuild-lock.txt
  53. +++ b/korebuild-lock.txt
  54. @@ -1,2 +1,2 @@
  55. -version:2.1.0-preview1-15626
  56. -commithash:fd6410e9c90c428bc01238372303ad09cb9ec889
  57. +version:2.1.0-preview1-15638
  58. +commithash:1d3a0c725dc6b8ae6b0e47800fd6b4d8f8b8d545
  59. diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionBuilderExtensions.cs b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionBuilderExtensions.cs
  60. index d6b827caab8..600e29fead2 100644
  61. --- a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionBuilderExtensions.cs
  62. +++ b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionBuilderExtensions.cs
  63. @@ -2,8 +2,8 @@
  64. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  65. using System;
  66. +using Microsoft.AspNetCore.Hosting.Server.Features;
  67. using Microsoft.AspNetCore.HttpsPolicy;
  68. -using Microsoft.AspNetCore.Rewrite;
  69. using Microsoft.Extensions.Configuration;
  70. using Microsoft.Extensions.DependencyInjection;
  71. using Microsoft.Extensions.Options;
  72. @@ -32,27 +32,7 @@ namespace Microsoft.AspNetCore.Builder
  73. var options = app.ApplicationServices.GetRequiredService<IOptions<HttpsRedirectionOptions>>().Value;
  74. - // The tls port set in options will have priority over the one in configuration.
  75. - var httpsPort = options.HttpsPort;
  76. - if (httpsPort == null)
  77. - {
  78. - // Only read configuration if there is no httpsPort
  79. - var config = app.ApplicationServices.GetRequiredService<IConfiguration>();
  80. - var configHttpsPort = config["HTTPS_PORT"];
  81. - // If the string isn't empty, try to parse it.
  82. - if (!string.IsNullOrEmpty(configHttpsPort)
  83. - && int.TryParse(configHttpsPort, out var intHttpsPort))
  84. - {
  85. - httpsPort = intHttpsPort;
  86. - }
  87. - }
  88. -
  89. - var rewriteOptions = new RewriteOptions();
  90. - rewriteOptions.AddRedirectToHttps(
  91. - options.RedirectStatusCode,
  92. - httpsPort);
  93. -
  94. - app.UseRewriter(rewriteOptions);
  95. + app.UseMiddleware<HttpsRedirectionMiddleware>(app.ServerFeatures.Get<IServerAddressesFeature>());
  96. return app;
  97. }
  98. diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs
  99. new file mode 100644
  100. index 00000000000..f500bbb2bce
  101. --- /dev/null
  102. +++ b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs
  103. @@ -0,0 +1,124 @@
  104. +// Copyright (c) .NET Foundation. All rights reserved.
  105. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  106. +
  107. +using System;
  108. +using System.Threading.Tasks;
  109. +using Microsoft.AspNetCore.Hosting.Server.Features;
  110. +using Microsoft.AspNetCore.Http;
  111. +using Microsoft.AspNetCore.Http.Extensions;
  112. +using Microsoft.AspNetCore.Http.Internal;
  113. +using Microsoft.Extensions.Configuration;
  114. +using Microsoft.Extensions.Options;
  115. +using Microsoft.Net.Http.Headers;
  116. +
  117. +namespace Microsoft.AspNetCore.HttpsPolicy
  118. +{
  119. + public class HttpsRedirectionMiddleware
  120. + {
  121. + private readonly RequestDelegate _next;
  122. + private int? _httpsPort;
  123. + private readonly int _statusCode;
  124. +
  125. + private readonly IServerAddressesFeature _serverAddressesFeature;
  126. + private readonly IConfiguration _config;
  127. +
  128. + /// <summary>
  129. + /// Initializes the HttpsRedirectionMiddleware
  130. + /// </summary>
  131. + /// <param name="next"></param>
  132. + /// <param name="serverAddressesFeature">The</param>
  133. + /// <param name="options"></param>
  134. + /// <param name="config"></param>
  135. + public HttpsRedirectionMiddleware(RequestDelegate next, IServerAddressesFeature serverAddressesFeature, IOptions<HttpsRedirectionOptions> options, IConfiguration config)
  136. + {
  137. + if (options == null)
  138. + {
  139. + throw new ArgumentNullException(nameof(options));
  140. + }
  141. + _config = config ?? throw new ArgumentException(nameof(config));
  142. + _next = next ?? throw new ArgumentNullException(nameof(next));
  143. + _serverAddressesFeature = serverAddressesFeature ?? throw new ArgumentNullException(nameof(serverAddressesFeature));
  144. +
  145. + var httpsRedirectionOptions = options.Value;
  146. + _httpsPort = httpsRedirectionOptions.HttpsPort;
  147. + _statusCode = httpsRedirectionOptions.RedirectStatusCode;
  148. + }
  149. +
  150. + /// <summary>
  151. + /// Invokes the HttpsRedirectionMiddleware
  152. + /// </summary>
  153. + /// <param name="context"></param>
  154. + /// <returns></returns>
  155. + public Task Invoke(HttpContext context)
  156. + {
  157. + if (context.Request.IsHttps)
  158. + {
  159. + return _next(context);
  160. + }
  161. +
  162. + if (!_httpsPort.HasValue)
  163. + {
  164. + CheckForHttpsPorts();
  165. + }
  166. +
  167. + var host = context.Request.Host;
  168. + if (_httpsPort != 443)
  169. + {
  170. + host = new HostString(host.Host, _httpsPort.Value);
  171. + }
  172. + else
  173. + {
  174. + host = new HostString(host.Host);
  175. + }
  176. +
  177. + var request = context.Request;
  178. + var redirectUrl = UriHelper.BuildAbsolute(
  179. + "https",
  180. + host,
  181. + request.PathBase,
  182. + request.Path,
  183. + request.QueryString);
  184. +
  185. + context.Response.StatusCode = _statusCode;
  186. + context.Response.Headers[HeaderNames.Location] = redirectUrl;
  187. +
  188. + return Task.CompletedTask;
  189. + }
  190. +
  191. + private void CheckForHttpsPorts()
  192. + {
  193. + // The IServerAddressesFeature will not be ready until the middleware is Invoked,
  194. + // Order for finding the HTTPS port:
  195. + // 1. Set in the HttpsRedirectionOptions
  196. + // 2. HTTPS_PORT environment variable
  197. + // 3. IServerAddressesFeature
  198. + // 4. 443 (or not set)
  199. +
  200. + _httpsPort = _config.GetValue<int?>("HTTPS_PORT");
  201. + if (_httpsPort.HasValue)
  202. + {
  203. + return;
  204. + }
  205. +
  206. + int? httpsPort = null;
  207. + foreach (var address in _serverAddressesFeature.Addresses)
  208. + {
  209. + var bindingAddress = BindingAddress.Parse(address);
  210. + if (bindingAddress.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
  211. + {
  212. + // If we find multiple different https ports specified, throw
  213. + if (httpsPort.HasValue && httpsPort != bindingAddress.Port)
  214. + {
  215. + throw new ArgumentException("Cannot determine the https port from IServerAddressesFeature, multiple values were found. " +
  216. + "Please set the desired port explicitly on HttpsRedirectionOptions.HttpsPort.");
  217. + }
  218. + else
  219. + {
  220. + httpsPort = bindingAddress.Port;
  221. + }
  222. + }
  223. + }
  224. + _httpsPort = httpsPort ?? 443;
  225. + }
  226. + }
  227. +}
  228. diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionOptions.cs b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionOptions.cs
  229. index 238f2eb4843..52f2b09def7 100644
  230. --- a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionOptions.cs
  231. +++ b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionOptions.cs
  232. @@ -16,10 +16,13 @@ namespace Microsoft.AspNetCore.HttpsPolicy
  233. public int RedirectStatusCode { get; set; } = StatusCodes.Status302Found;
  234. /// <summary>
  235. - /// The TLS port to be added to the redirected URL.
  236. + /// The HTTPS port to be added to the redirected URL.
  237. /// </summary>
  238. /// <remarks>
  239. - /// Defaults to 443 if not provided.
  240. + /// If the HttpsPort is not set, we will try to get the HttpsPort from the following:
  241. + /// 1. HTTPS_PORT environment variable
  242. + /// 2. IServerAddressesFeature
  243. + /// 3. 443 (or not set)
  244. /// </remarks>
  245. public int? HttpsPort { get; set; }
  246. }
  247. diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/Microsoft.AspNetCore.HttpsPolicy.csproj b/src/Microsoft.AspNetCore.HttpsPolicy/Microsoft.AspNetCore.HttpsPolicy.csproj
  248. index b68d33b7dc1..ee7e611a475 100644
  249. --- a/src/Microsoft.AspNetCore.HttpsPolicy/Microsoft.AspNetCore.HttpsPolicy.csproj
  250. +++ b/src/Microsoft.AspNetCore.HttpsPolicy/Microsoft.AspNetCore.HttpsPolicy.csproj
  251. @@ -11,6 +11,10 @@
  252. </PropertyGroup>
  253. <ItemGroup>
  254. - <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Rewrite\Microsoft.AspNetCore.Rewrite.csproj" />
  255. + <PackageReference Include="Microsoft.AspNetCore.Http" Version="$(MicrosoftAspNetCoreHttpAbstractionsPackageVersion)" />
  256. + <PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="$(MicrosoftAspNetCoreHttpExtensionsPackageVersion)" />
  257. + <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsConfigurationBinderPackageVersion)" />
  258. + <PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
  259. + <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="$(MicrosoftAspNetCoreHostingAbstractionsPackageVersion)" />
  260. </ItemGroup>
  261. </Project>
  262. diff --git a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs
  263. index 49a3d0a29a2..aa874fb8cd9 100644
  264. --- a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs
  265. +++ b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs
  266. @@ -8,7 +8,9 @@ using System.Net.Http;
  267. using System.Threading.Tasks;
  268. using Microsoft.AspNetCore.Builder;
  269. using Microsoft.AspNetCore.Hosting;
  270. +using Microsoft.AspNetCore.Hosting.Server.Features;
  271. using Microsoft.AspNetCore.Http;
  272. +using Microsoft.AspNetCore.Http.Features;
  273. using Microsoft.AspNetCore.TestHost;
  274. using Microsoft.Extensions.DependencyInjection;
  275. using Microsoft.Net.Http.Headers;
  276. @@ -55,7 +57,9 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  277. });
  278. });
  279. - var server = new TestServer(builder);
  280. + var featureCollection = new FeatureCollection();
  281. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  282. + var server = new TestServer(builder, featureCollection);
  283. var client = server.CreateClient();
  284. var request = new HttpRequestMessage(HttpMethod.Get, "");
  285. diff --git a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs
  286. index aabba1324ea..14f7c5444f5 100644
  287. --- a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs
  288. +++ b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs
  289. @@ -8,7 +8,9 @@ using System.Net.Http;
  290. using System.Threading.Tasks;
  291. using Microsoft.AspNetCore.Builder;
  292. using Microsoft.AspNetCore.Hosting;
  293. +using Microsoft.AspNetCore.Hosting.Server.Features;
  294. using Microsoft.AspNetCore.Http;
  295. +using Microsoft.AspNetCore.Http.Features;
  296. using Microsoft.AspNetCore.TestHost;
  297. using Microsoft.Extensions.DependencyInjection;
  298. using Microsoft.Net.Http.Headers;
  299. @@ -34,7 +36,9 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  300. });
  301. });
  302. - var server = new TestServer(builder);
  303. + var featureCollection = new FeatureCollection();
  304. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  305. + var server = new TestServer(builder, featureCollection);
  306. var client = server.CreateClient();
  307. var request = new HttpRequestMessage(HttpMethod.Get, "");
  308. @@ -73,7 +77,9 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  309. });
  310. });
  311. - var server = new TestServer(builder);
  312. + var featureCollection = new FeatureCollection();
  313. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  314. + var server = new TestServer(builder, featureCollection);
  315. var client = server.CreateClient();
  316. var request = new HttpRequestMessage(HttpMethod.Get, "");
  317. @@ -111,7 +117,9 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  318. });
  319. });
  320. - var server = new TestServer(builder);
  321. + var featureCollection = new FeatureCollection();
  322. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  323. + var server = new TestServer(builder, featureCollection);
  324. var client = server.CreateClient();
  325. var request = new HttpRequestMessage(HttpMethod.Get, "");
  326. @@ -123,13 +131,17 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  327. }
  328. [Theory]
  329. - [InlineData(null, null, "https://localhost/")]
  330. - [InlineData(null, "5000", "https://localhost:5000/")]
  331. - [InlineData(null, "443", "https://localhost/")]
  332. - [InlineData(443, "5000", "https://localhost/")]
  333. - [InlineData(4000, "5000", "https://localhost:4000/")]
  334. - [InlineData(5000, null, "https://localhost:5000/")]
  335. - public async Task SetHttpsPortEnvironmentVariable_ReturnsCorrectStatusCodeOnResponse(int? optionsHttpsPort, string configHttpsPort, string expectedUrl)
  336. + [InlineData(null, null, null, "https://localhost/")]
  337. + [InlineData(null, null, "https://localhost:4444/", "https://localhost:4444/")]
  338. + [InlineData(null, null, "https://localhost:443/", "https://localhost/")]
  339. + [InlineData(null, null, "http://localhost:5044/", "https://localhost/")]
  340. + [InlineData(null, null, "https://localhost/", "https://localhost/")]
  341. + [InlineData(null, "5000", "https://localhost:4444/", "https://localhost:5000/")]
  342. + [InlineData(null, "443", "https://localhost:4444/", "https://localhost/")]
  343. + [InlineData(443, "5000", "https://localhost:4444/", "https://localhost/")]
  344. + [InlineData(4000, "5000", "https://localhost:4444/", "https://localhost:4000/")]
  345. + [InlineData(5000, null, "https://localhost:4444/", "https://localhost:5000/")]
  346. + public async Task SetHttpsPortEnvironmentVariableAndServerFeature_ReturnsCorrectStatusCodeOnResponse(int? optionsHttpsPort, string configHttpsPort, string serverAddressFeatureUrl, string expectedUrl)
  347. {
  348. var builder = new WebHostBuilder()
  349. .ConfigureServices(services =>
  350. @@ -147,8 +159,18 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  351. return context.Response.WriteAsync("Hello world");
  352. });
  353. });
  354. +
  355. builder.UseSetting("HTTPS_PORT", configHttpsPort);
  356. - var server = new TestServer(builder);
  357. +
  358. + var featureCollection = new FeatureCollection();
  359. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  360. +
  361. + var server = new TestServer(builder, featureCollection);
  362. + if (serverAddressFeatureUrl != null)
  363. + {
  364. + server.Features.Get<IServerAddressesFeature>().Addresses.Add(serverAddressFeatureUrl);
  365. + }
  366. +
  367. var client = server.CreateClient();
  368. var request = new HttpRequestMessage(HttpMethod.Get, "");
  369. @@ -157,5 +179,106 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests
  370. Assert.Equal(expectedUrl, response.Headers.Location.ToString());
  371. }
  372. +
  373. + [Fact]
  374. + public async Task SetServerAddressesFeature_SingleHttpsAddress_Success()
  375. + {
  376. + var builder = new WebHostBuilder()
  377. + .ConfigureServices(services =>
  378. + {
  379. + services.AddHttpsRedirection(options =>
  380. + {
  381. + });
  382. + })
  383. + .Configure(app =>
  384. + {
  385. + app.UseHttpsRedirection();
  386. + app.Run(context =>
  387. + {
  388. + return context.Response.WriteAsync("Hello world");
  389. + });
  390. + });
  391. +
  392. + var featureCollection = new FeatureCollection();
  393. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  394. + var server = new TestServer(builder, featureCollection);
  395. +
  396. + server.Features.Get<IServerAddressesFeature>().Addresses.Add("https://localhost:5050");
  397. + var client = server.CreateClient();
  398. +
  399. + var request = new HttpRequestMessage(HttpMethod.Get, "");
  400. +
  401. + var response = await client.SendAsync(request);
  402. +
  403. + Assert.Equal("https://localhost:5050/", response.Headers.Location.ToString());
  404. + }
  405. +
  406. + [Fact]
  407. + public async Task SetServerAddressesFeature_MultipleHttpsAddresses_ThrowInMiddleware()
  408. + {
  409. + var builder = new WebHostBuilder()
  410. + .ConfigureServices(services =>
  411. + {
  412. + services.AddHttpsRedirection(options =>
  413. + {
  414. + });
  415. + })
  416. + .Configure(app =>
  417. + {
  418. + app.UseHttpsRedirection();
  419. + app.Run(context =>
  420. + {
  421. + return context.Response.WriteAsync("Hello world");
  422. + });
  423. + });
  424. +
  425. + var featureCollection = new FeatureCollection();
  426. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  427. + var server = new TestServer(builder, featureCollection);
  428. +
  429. + server.Features.Get<IServerAddressesFeature>().Addresses.Add("https://localhost:5050");
  430. + server.Features.Get<IServerAddressesFeature>().Addresses.Add("https://localhost:5051");
  431. +
  432. + var client = server.CreateClient();
  433. +
  434. + var request = new HttpRequestMessage(HttpMethod.Get, "");
  435. +
  436. + await Assert.ThrowsAsync<ArgumentException>(async () => await client.SendAsync(request));
  437. + }
  438. +
  439. + [Fact]
  440. + public async Task SetServerAddressesFeature_MultipleHttpsAddressesWithSamePort_Success()
  441. + {
  442. + var builder = new WebHostBuilder()
  443. + .ConfigureServices(services =>
  444. + {
  445. + services.AddHttpsRedirection(options =>
  446. + {
  447. + });
  448. + })
  449. + .Configure(app =>
  450. + {
  451. + app.UseHttpsRedirection();
  452. + app.Run(context =>
  453. + {
  454. + return context.Response.WriteAsync("Hello world");
  455. + });
  456. + });
  457. +
  458. + var featureCollection = new FeatureCollection();
  459. + featureCollection.Set<IServerAddressesFeature>(new ServerAddressesFeature());
  460. + var server = new TestServer(builder, featureCollection);
  461. +
  462. + server.Features.Get<IServerAddressesFeature>().Addresses.Add("https://localhost:5050");
  463. + server.Features.Get<IServerAddressesFeature>().Addresses.Add("https://localhost:5050");
  464. +
  465. + var client = server.CreateClient();
  466. +
  467. + var request = new HttpRequestMessage(HttpMethod.Get, "");
  468. +
  469. + var response = await client.SendAsync(request);
  470. +
  471. + Assert.Equal("https://localhost:5050/", response.Headers.Location.ToString());
  472. + }
  473. }
  474. }