HttpsRedirectionMiddleware should not redirect requests to the same port
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [X] 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
1. Redirection should fail, rather than redirect to the same port
2. There should be logging for this particular kind of redirection failure
3. 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
```csharp
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
```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
9b4c5332ef0ef437120bd06454d2bbd335e030ac
### 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.
Contributor guide
Assessment
This issue has not been assessed yet.