-
Notifications
You must be signed in to change notification settings - Fork 838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E2E tests for different header encodings #760
Conversation
6670731
to
0c977e2
Compare
Response headers (not supported yet): dotnet/aspnetcore#26334, #440 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only style comments so far.
Few error handling issues discovered with this:
The last two points stem from reverse proxy catching and translating only exception from |
The error you showed on #765 is a configuration issue with Destination Addresses. Can you show the error that would be hit if Kestrel accepted UTF-8 or Latin1 headers but then they were rejected when copying to HttpClient? I know the callstack will be similar, but I want to be clear on the specific exception thrown so we can handle it.
|
For headers it won't throw atm from
Although a custom transform could cause an exception here since
|
Yeah, I register the handler like this:
|
Hmm, that implies an app code bug rather than an issue proxying the request. It's probably best to let those escape and be reported up stack. The client would see a 500 response which seems appropriate. If any of the built in transforms could cause an exception then I think we'd address those in the transform. |
We should catch that one since it's specific to the request/response data. |
.NET 3.1 HttpClient AppSwitch for Latin1 headers (nothing for UTF-8): Do we want to enable process wide app switch? Or should we only document this option for .NET 3.1? Kestrel 3.1 |
Docs only. app switches don't test well. Just do a manual test. |
a37e772
to
1530881
Compare
d21d96a
to
7cb6e49
Compare
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}) | ||
.ConfigureWebHost(webBuilder => webBuilder.UseKestrel(kestrel => | ||
{ | ||
kestrel.RequestHeaderEncodingSelector = _ => Encoding.Latin1; | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ConfigureWebHost and ConfigureWebHostDefaults are redundant. Also call ConfigureKestrel rather than UseKestrel here, UseKestrel was already called by ConfigureWebHostDefaults.
.ConfigureWebHostDefaults(webBuilder => | |
{ | |
webBuilder.UseStartup<Startup>(); | |
}) | |
.ConfigureWebHost(webBuilder => webBuilder.UseKestrel(kestrel => | |
{ | |
kestrel.RequestHeaderEncodingSelector = _ => Encoding.Latin1; | |
})); | |
.ConfigureWebHostDefaults(webBuilder => | |
{ | |
webBuilder.UseStartup<Startup>(); | |
webBuilder.ConfigureKestrel(kestrelOptions => | |
{ | |
kestrelOptions.RequestHeaderEncodingSelector = _ => Encoding.Latin1; | |
}) | |
}); |
AppContext.SetSwitch("Microsoft.AspNetCore.Server.Kestrel.Latin1RequestHeaders", true); | ||
``` | ||
|
||
At the moment, there is no solution for changing encoding for response headers, only ASCII is accepted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... in Kestrel.
Link to dotnet/aspnetcore#26334.
// Clear the response since status code, reason and some headers might have already been copied and we want clean 502 response. | ||
context.Response.Clear(); | ||
context.Response.StatusCode = StatusCodes.Status502BadGateway; | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to dispose the destinationResponse to avoid a leak.
using var httpClient = new HttpClient(); | ||
using var response = await httpClient.GetAsync(proxy.GetAddress()); | ||
|
||
Assert.NotNull(proxyError); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the enum and the exception type and message here so we'll know if it starts failing for another reason.
All is available only for .NET 5, there are no equivalents for .NET Core 3.1 AFAIK.
1. Proxying request with UTF8/Latin1 header values
1.a. Proxy server needs:
kestrel.RequestHeaderEncodingSelector
:reverse-proxy/test/ReverseProxy.FunctionalTests/Common/TestEnvironment.cs
Lines 134 to 137 in 6670731
This can be configured manually in
ConfigureWebHost
.1.b. Proxy client needs:
RequestHeaderEncodingSelector
:reverse-proxy/test/ReverseProxy.FunctionalTests/HeaderEncodingTests.cs
Line 250 in 6670731
This can be achieved in custom
IProxyHttpClientFactory
implementation, however the default implementation contains non-trivial amount of code and is internal, which leads to copy-pasting quite a bit of code.We could also add configuration for request header encoding, which can be per header name, and we would ensure that receiving server and sending client are in sync and expect the same encoding. However, that would need some more effort.
2. Proxying back response with UTF8/Latin1 header values
2.a. Proxy client needs:
ResponseHeaderEncodingSelector
:reverse-proxy/test/ReverseProxy.FunctionalTests/HeaderEncodingTests.cs
Line 251 in 6670731
Achievable the same way as 1.b.
2.b. Proxy server fails with:
System.InvalidOperationException: Invalid non-ASCII or control character in header
I haven't found
RequestHeaderEncodingSelector
equivalent for response headers. I don't know if there's a way to do this atm.We could use transforms to encode the header value in ASCII characters as this RFC describes, but I don't know if clients in general can handle that on its own or the consumer would need to parse it manually.
cc: @Tratcher
Contributes to #154