Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
If HttpsRedirectionMiddleware redirects a request from http://localhost:5001 to https://localhost:5001, the redirected request will fail with a protocol error, since the port isn't using https. When you accidentally get into this state, it can be hard to tell what's happening, so we should also improve the logging.
Expected Behavior
- Redirection should fail, rather than redirect to the same port
- There should be logging for this particular kind of redirection failure
- If possible, there should be logging about the conflicting configurations that led to the middleware thinking the port was accepting https
Steps To Reproduce
Make a new webapi project:
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5001);
});
var app = builder.Build();
app.UseHttpsRedirection();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Properties/launchSettings.json
{
"profiles": {
"Kestrel": {
"commandName": "Project",
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Note that launchSettings does not specify an application url - this is not the default behavior.
$ curl -v http://localhost:5001/
* Trying [::1]:5001...
* Connected to localhost (::1) port 5001
> GET / HTTP/1.1
> Host: localhost:5001
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/1.1 307 Temporary Redirect
< Content-Length: 0
< Date: Fri, 16 Feb 2024 19:59:12 GMT
< Server: Kestrel
< Location: https://localhost:5001/
<
* Connection #0 to host localhost left intact
Exceptions (if any)
No response
.NET Version
Anything else?
It happens in HttpSys as well, setting UrlPrefix, rather than calling ListenAnyIP
.
AFAICT, because VS is unaware that the URL is being configured in code, it injects
ASPNETCORE_HTTPS_PORT=5001
ASPNETCORE_URLS=https://localhost:5001/;http://localhost:5000/
As a result, the middleware sees that https requests should go to port 5001. Without the env var, the middleware would search existing endpoints to find one supporting https. Since there isn't one in this particular repro, it would log a redirection failure and accept the http request as-is.
If the configuration in code specified a port other than 5001, the browser would at least show the user redirection to a port they weren't expecting, but it would still likely fail if the server weren't listening on that port.