parent
8b99354419
commit
b670246e3d
|
|
@ -1,8 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<UserSecretsId>aspnetcore-MetaPackagesSampleApp-20170406180413</UserSecretsId>
|
||||
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -16,19 +16,16 @@ namespace SampleApp
|
|||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
HelloWorld();
|
||||
|
||||
CustomUrl();
|
||||
|
||||
CustomRouter();
|
||||
|
||||
CustomApplicationBuilder();
|
||||
|
||||
StartupClass(args);
|
||||
|
||||
HostBuilderWithWebHost(args);
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
|
||||
private static void HelloWorld()
|
||||
{
|
||||
using (WebHost.Start(context => context.Response.WriteAsync("Hello, World!")))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
// 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.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace SampleApp
|
||||
|
|
@ -15,12 +21,50 @@ namespace SampleApp
|
|||
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
public void Configure(IApplicationBuilder app, IConfiguration config)
|
||||
{
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
await context.Response.WriteAsync($"Hello from {nameof(Startup)}!");
|
||||
await context.Response.WriteAsync($"Hello from {context.Request.GetDisplayUrl()}\r\n");
|
||||
await context.Response.WriteAsync("\r\n");
|
||||
|
||||
await context.Response.WriteAsync("Headers:\r\n");
|
||||
foreach (var header in context.Request.Headers)
|
||||
{
|
||||
await context.Response.WriteAsync($"{header.Key}: {header.Value}\r\n");
|
||||
}
|
||||
await context.Response.WriteAsync("\r\n");
|
||||
|
||||
await context.Response.WriteAsync("Connection:\r\n");
|
||||
await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + "\r\n");
|
||||
await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + "\r\n");
|
||||
await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + "\r\n");
|
||||
await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + "\r\n");
|
||||
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + "\r\n");
|
||||
await context.Response.WriteAsync("\r\n");
|
||||
|
||||
await context.Response.WriteAsync("Environment Variables:\r\n");
|
||||
var vars = Environment.GetEnvironmentVariables();
|
||||
foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var value = vars[key];
|
||||
await context.Response.WriteAsync($"{key}: {value}\r\n");
|
||||
}
|
||||
await context.Response.WriteAsync("\r\n");
|
||||
|
||||
await context.Response.WriteAsync("Config:\r\n");
|
||||
await ShowConfig(context.Response, config);
|
||||
await context.Response.WriteAsync("\r\n");
|
||||
});
|
||||
}
|
||||
|
||||
private static async Task ShowConfig(HttpResponse response, IConfiguration config)
|
||||
{
|
||||
foreach (var pair in config.GetChildren())
|
||||
{
|
||||
await response.WriteAsync($"{pair.Path}: {pair.Value}\r\n");
|
||||
await ShowConfig(response, pair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"AllowedHosts": "example.com;localhost",
|
||||
"Kestrel": {
|
||||
"EndPoints": {
|
||||
"Http": {
|
||||
"Url": "http://localhost:5005"
|
||||
},
|
||||
"Https": {
|
||||
"Url": "https://localhost:5006"
|
||||
}
|
||||
|
||||
// To enable HTTPS using a certificate file, set the path to a .pfx file in
|
||||
// the "Path" property below and configure the password in user secrets.
|
||||
// The "Password" property should be set in user secrets.
|
||||
//"HttpsInlineCertFile": {
|
||||
// "Url": "http://localhost:5005"
|
||||
// "Certificate": {
|
||||
// "Path": "<path to .pfx file>",
|
||||
// "Password: "<cert password>"
|
||||
// }
|
||||
//},
|
||||
|
||||
//"HttpsInlineCertStore": {
|
||||
// "Url": "http://localhost:5005"
|
||||
// "Certificate": {
|
||||
// "Subject": "",
|
||||
// "Store": "",
|
||||
// "Location": "",
|
||||
// "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired)
|
||||
// }
|
||||
//},
|
||||
|
||||
// This uses the cert defined under Certificates/Default or the development cert.
|
||||
//"HttpsDefaultCert": {
|
||||
// "Url": "http://localhost:5005"
|
||||
//}
|
||||
}
|
||||
},
|
||||
"Certificates": {
|
||||
//"Default": {
|
||||
// "Path": "<file>",
|
||||
// "Password": "<password>"
|
||||
//},
|
||||
|
||||
// From cert store:
|
||||
//"Default": {
|
||||
// "Subject": "",
|
||||
// "Store": "",
|
||||
// "Location": "",
|
||||
// "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired certificates)
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +1,2 @@
|
|||
{
|
||||
"AllowedHosts": "example.com;localhost",
|
||||
"Kestrel": {
|
||||
"EndPoints": {
|
||||
"Http": {
|
||||
"Url": "http://localhost:5005"
|
||||
}
|
||||
|
||||
// To enable HTTPS using a certificate file, set the path to a .pfx file in
|
||||
// the "Path" property below and configure the password in user secrets.
|
||||
// The "Password" property should be set in user secrets.
|
||||
//"HttpsInlineCertFile": {
|
||||
// "Url": "http://localhost:5005"
|
||||
// "Certificate": {
|
||||
// "Path": "<path to .pfx file>",
|
||||
// "Password: "<cert password>"
|
||||
// }
|
||||
//},
|
||||
|
||||
//"HttpsInlineCertStore": {
|
||||
// "Url": "http://localhost:5005"
|
||||
// "Certificate": {
|
||||
// "Subject": "",
|
||||
// "Store": "",
|
||||
// "Location": "",
|
||||
// "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired)
|
||||
// }
|
||||
//},
|
||||
|
||||
// This uses the cert defined under Certificates/Default or the development cert.
|
||||
//"HttpsDefaultCert": {
|
||||
// "Url": "http://localhost:5005"
|
||||
//}
|
||||
}
|
||||
},
|
||||
"Certificates": {
|
||||
//"Default": {
|
||||
// "Path": "<file>",
|
||||
// "Password": "<password>"
|
||||
//},
|
||||
|
||||
// From cert store:
|
||||
//"Default": {
|
||||
// "Subject": "",
|
||||
// "Store": "",
|
||||
// "Location": "",
|
||||
// "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired certificates)
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// 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 Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Microsoft.AspNetCore
|
||||
{
|
||||
internal class ForwardedHeadersStartupFilter : IStartupFilter
|
||||
{
|
||||
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||
{
|
||||
return app =>
|
||||
{
|
||||
app.UseForwardedHeaders();
|
||||
next(app);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore;
|
||||
|
||||
|
|
@ -15,6 +15,8 @@ namespace Microsoft.Extensions.Hosting
|
|||
/// <remarks>
|
||||
/// The following defaults are applied to the <see cref="IWebHostBuilder"/>:
|
||||
/// use Kestrel as the web server and configure it using the application's configuration providers,
|
||||
/// adds the HostFiltering middleware,
|
||||
/// adds the ForwardedHeaders middleware if ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,
|
||||
/// and enable IIS integration.
|
||||
/// </remarks>
|
||||
/// <param name="builder">The <see cref="IHostBuilder" /> instance to configure</param>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.HostFiltering;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -124,6 +125,8 @@ namespace Microsoft.AspNetCore
|
|||
/// load <see cref="IConfiguration"/> from User Secrets when <see cref="IHostEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,
|
||||
/// load <see cref="IConfiguration"/> from environment variables,
|
||||
/// configure the <see cref="ILoggerFactory"/> to log to the console and debug output,
|
||||
/// adds the HostFiltering middleware,
|
||||
/// adds the ForwardedHeaders middleware if ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,
|
||||
/// and enable IIS integration.
|
||||
/// </remarks>
|
||||
/// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
|
||||
|
|
@ -142,6 +145,8 @@ namespace Microsoft.AspNetCore
|
|||
/// load <see cref="IConfiguration"/> from environment variables,
|
||||
/// load <see cref="IConfiguration"/> from supplied command line args,
|
||||
/// configure the <see cref="ILoggerFactory"/> to log to the console and debug output,
|
||||
/// adds the HostFiltering middleware,
|
||||
/// adds the ForwardedHeaders middleware if ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,
|
||||
/// and enable IIS integration.
|
||||
/// </remarks>
|
||||
/// <param name="args">The command line args.</param>
|
||||
|
|
@ -224,6 +229,20 @@ namespace Microsoft.AspNetCore
|
|||
|
||||
services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
|
||||
|
||||
if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
// Only loopback proxies are allowed by default. Clear that restriction because forwarders are
|
||||
// being enabled by explicit configuration.
|
||||
options.KnownNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
});
|
||||
|
||||
services.AddTransient<IStartupFilter, ForwardedHeadersStartupFilter>();
|
||||
}
|
||||
|
||||
services.AddRouting();
|
||||
})
|
||||
.UseIIS()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore" />
|
||||
<Reference Include="Microsoft.AspNetCore.TestHost" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ using System.Diagnostics.Tracing;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.HostFiltering;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -57,6 +59,35 @@ namespace Microsoft.AspNetCore.Tests
|
|||
Assert.Contains("NewHost", options.AllowedHosts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WebHostConfiguration_EnablesForwardedHeadersFromConfig()
|
||||
{
|
||||
using var host = WebHost.CreateDefaultBuilder()
|
||||
.ConfigureAppConfiguration(configBuilder =>
|
||||
{
|
||||
configBuilder.AddInMemoryCollection(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("FORWARDEDHEADERS_ENABLED", "true" ),
|
||||
});
|
||||
})
|
||||
.UseTestServer()
|
||||
.Configure(app =>
|
||||
{
|
||||
Assert.True(app.Properties.ContainsKey("ForwardedHeadersAdded"), "Forwarded Headers");
|
||||
app.Run(context =>
|
||||
{
|
||||
Assert.Equal("https", context.Request.Scheme);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}).Build();
|
||||
|
||||
await host.StartAsync();
|
||||
var client = host.GetTestClient();
|
||||
client.DefaultRequestHeaders.Add("x-forwarded-proto", "https");
|
||||
var result = await client.GetAsync("http://localhost/");
|
||||
result.EnsureSuccessStatusCode();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDefaultBuilder_RegistersRouting()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
{
|
||||
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder ConfigureTestContainer<TContainer>(this Microsoft.AspNetCore.Hosting.IWebHostBuilder webHostBuilder, System.Action<TContainer> servicesConfiguration) { throw null; }
|
||||
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder ConfigureTestServices(this Microsoft.AspNetCore.Hosting.IWebHostBuilder webHostBuilder, System.Action<Microsoft.Extensions.DependencyInjection.IServiceCollection> servicesConfiguration) { throw null; }
|
||||
public static System.Net.Http.HttpClient GetTestClient(this Microsoft.AspNetCore.Hosting.IWebHost host) { throw null; }
|
||||
public static Microsoft.AspNetCore.TestHost.TestServer GetTestServer(this Microsoft.AspNetCore.Hosting.IWebHost host) { throw null; }
|
||||
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseSolutionRelativeContentRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, string solutionRelativePath, string solutionName = "*.sln") { throw null; }
|
||||
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseSolutionRelativeContentRoot(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, string solutionRelativePath, string applicationBasePath, string solutionName = "*.sln") { throw null; }
|
||||
public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseTestServer(this Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) { throw null; }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Internal;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
|
|
@ -21,6 +22,26 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the TestServer from the host services.
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <returns></returns>
|
||||
public static TestServer GetTestServer(this IWebHost host)
|
||||
{
|
||||
return (TestServer)host.Services.GetRequiredService<IServer>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the test client from the TestServer in the host services.
|
||||
/// </summary>
|
||||
/// <param name="host"></param>
|
||||
/// <returns></returns>
|
||||
public static HttpClient GetTestClient(this IWebHost host)
|
||||
{
|
||||
return host.GetTestServer().CreateClient();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder ConfigureTestServices(this IWebHostBuilder webHostBuilder, Action<IServiceCollection> servicesConfiguration)
|
||||
{
|
||||
if (webHostBuilder == null)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -9,6 +9,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static class ForwardedHeadersExtensions
|
||||
{
|
||||
private const string ForwardedHeadersAdded = "ForwardedHeadersAdded";
|
||||
|
||||
/// <summary>
|
||||
/// Forwards proxied headers onto current request
|
||||
/// </summary>
|
||||
|
|
@ -21,7 +23,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
return builder.UseMiddleware<ForwardedHeadersMiddleware>();
|
||||
// Don't add more than one instance of this middleware to the pipeline using the options from the DI container.
|
||||
// Doing so could cause a request to be processed multiple times and the ForwardLimit to be exceeded.
|
||||
if (!builder.Properties.ContainsKey(ForwardedHeadersAdded))
|
||||
{
|
||||
builder.Properties[ForwardedHeadersAdded] = true;
|
||||
return builder.UseMiddleware<ForwardedHeadersMiddleware>();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -865,5 +866,66 @@ namespace Microsoft.AspNetCore.HttpOverrides
|
|||
|
||||
Assert.Equal(expectedRemoteIp, context.Connection.RemoteIpAddress.ToString());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1, "httpa, httpb, httpc", "httpc", "httpa,httpb")]
|
||||
[InlineData(2, "httpa, httpb, httpc", "httpb", "httpa")]
|
||||
public async Task ForwardersWithDIOptionsRunsOnce(int limit, string header, string expectedScheme, string remainingHeader)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
|
||||
options.KnownProxies.Clear();
|
||||
options.KnownNetworks.Clear();
|
||||
options.ForwardLimit = limit;
|
||||
});
|
||||
})
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseForwardedHeaders();
|
||||
app.UseForwardedHeaders();
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var context = await server.SendAsync(c =>
|
||||
{
|
||||
c.Request.Headers["X-Forwarded-Proto"] = header;
|
||||
});
|
||||
|
||||
Assert.Equal(expectedScheme, context.Request.Scheme);
|
||||
Assert.Equal(remainingHeader, context.Request.Headers["X-Forwarded-Proto"].ToString());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1, "httpa, httpb, httpc", "httpb", "httpa")]
|
||||
[InlineData(2, "httpa, httpb, httpc", "httpa", "")]
|
||||
public async Task ForwardersWithDirectOptionsRunsTwice(int limit, string header, string expectedScheme, string remainingHeader)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
var options = new ForwardedHeadersOptions
|
||||
{
|
||||
ForwardedHeaders = ForwardedHeaders.XForwardedProto,
|
||||
ForwardLimit = limit,
|
||||
};
|
||||
options.KnownProxies.Clear();
|
||||
options.KnownNetworks.Clear();
|
||||
app.UseForwardedHeaders(options);
|
||||
app.UseForwardedHeaders(options);
|
||||
});
|
||||
var server = new TestServer(builder);
|
||||
|
||||
var context = await server.SendAsync(c =>
|
||||
{
|
||||
c.Request.Headers["X-Forwarded-Proto"] = header;
|
||||
});
|
||||
|
||||
Assert.Equal(expectedScheme, context.Request.Scheme);
|
||||
Assert.Equal(remainingHeader, context.Request.Headers["X-Forwarded-Proto"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue