-
Notifications
You must be signed in to change notification settings - Fork 5
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
Pound symbols (#) don't seem to be encoded when matching on uri #29
Comments
Thanks for reporting. Could it be because the actual request URI sent via the client is not encoded and it is thus considered an URI fragment (and not part of the query string value)? https://en.wikipedia.org/wiki/URI_fragment eg. for:
Because if true, you will not be able to intercept this via If not, I will have a look at it. |
If we encode the request uri client side then we get spaces being decoded and pound symbols remain encoded. e.g. if we change the above repro to be we get this as a result...
Note the partial decoding in the Seen request uri. I would expect to either see a full decoding or the request uri to remain encoded. |
The request URI matcher does consider query string encoding according to RFC-3986. Internally, everything is decoded before a match is performed. What you see in the exception details is just the way Please note that the .RequestUri("http://localhost/controller?*") It seems to work as intended (provided you do the above), as long as the URL requested via [Theory]
[MemberData(nameof(QueryStringTestCases))]
public async Task MatchingTestCases(Action<RequestMatching> matchQueryString)
{
MockHttpHandler mockHttp = new MockHttpHandler();
// Configure setup(s).
mockHttp
.When(matching =>
{
matchQueryString(matching.RequestUri("http://localhost/controller?*"));
})
.Respond(HttpStatusCode.OK, "ok")
.Verifiable();
var client = new HttpClient(mockHttp);
HttpResponseMessage response = await client.GetAsync("http://localhost/controller?param=Hello%20World%23");
// Verify expectations (WILL PASS).
mockHttp.Verify();
}
[Theory]
[MemberData(nameof(QueryStringTestCases))]
public async Task NotMatchingTestCases(Action<RequestMatching> matchQueryString)
{
MockHttpHandler mockHttp = new MockHttpHandler();
// Configure setup(s).
_sut
.When(matching =>
{
matchQueryString(matching.RequestUri("http://localhost/controller?*"));
})
.Respond(HttpStatusCode.OK, "ok")
.Verifiable();
var client = new HttpClient(mockHttp);
// This won't work as the # is not part of the query param value but actually a fragment
HttpResponseMessage response = await client.GetAsync("http://localhost/controller?param=Hello World#");
// Verify expectations (WILL BREAK).
mockHttp.Verify();
}
public static IEnumerable<object[]> QueryStringTestCases()
{
yield return new object[] { (Action<RequestMatching>)(m => m.QueryString("?param=Hello%20World%23")) }; // Must encode ourselves with this overload (see wiki)
yield return new object[] { (Action<RequestMatching>)(m => m.QueryString("?param=Hello World%23")) }; // Must encode ourselves with this overload (see wiki)
yield return new object[] { (Action<RequestMatching>)(m => m.QueryString("param", "Hello World#")) };
yield return new object[] { (Action<RequestMatching>)(m => m.QueryString(new Dictionary<string, IEnumerable<string>> { { "param", new[] { "Hello World#" } } })) };
yield return new object[] { (Action<RequestMatching>)(m => m.QueryString(new NameValueCollection { { "param", "Hello World#" } })) };
} I will make note to improve the member XML docs and wiki to clarify the above nuances more. It is documented but not very evident and this can definitely be improved. |
As far as this case, I will look into it further:
But it could be similar if you were sending with this request:
That said, this matcher 'does' work somewhat different, so I will investigate. |
Thank you very much for the in depth responses and the time you've taken to look at this.
If this is true then something I don't understand then is why these two fail to match....
The only scenario that matches here is |
The issue is the same, the
|
I understand now and thanks again for your help. |
When query strings have pound symbols (#) in them the decoded value does not appear to get encoded when determining if it matches the expected uri. I've tried several methods on the api but they all more or less have the same result.
Repro:
The text was updated successfully, but these errors were encountered: