xamarin-macios/tests/monotouch-test/System.Net.Http
Rolf Bjarne Kvinge 59e84a5e6c
[NSUrlSessionHandler] Only update the request's RequestUri if a redirection occurred. Fixes #20629. (#20633)
The logic to update the request's RequestUri is somewhat old:

518ac1bf19

but it makes sense to do so.

Some testing with a console app, also revealed that a plain .NET does this in
case of a redirect:

```cs
async static Task Main ()
{
    var client = new HttpClient () { BaseAddress = new Uri("https://httpbin.org") };
    var request = new HttpRequestMessage (HttpMethod.Get,
        "/redirect-to?url=https%3A%2F%2Fmicrosoft.com&status_code=302&queries[]={}"
    );
    Console.WriteLine ($"Request uri 1: {request.RequestUri}");
    var response = await client.SendAsync(request);
    Console.WriteLine ($"Request uri 2: {request.RequestUri}");
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine ((int) response.StatusCode);
    Console.WriteLine(content.Length);
}
```

prints:

```
Request uri 1: /redirect-to?url=https%3A%2F%2Fmicrosoft.com&status_code=302&queries[]={}
Request uri 2: https://www.microsoft.com/es-es/
200
201252
```

Further looking into .NET's code, `SocketsHttpHandler` updates RequestUri after
following a redirect:

f5eb26e4da/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs (L65-L66)

So it seems the expected behavior is to update RequestUri only in case of a
redirect.

Now the question becomes: how to detect whether we're a redirect or not?
Contrary to `SocketsHttpHandler`, we don't do the actual redirect, it's
handled transparently by `NSUrlSession`.

Fortunately `NSUrlSessionTask` has two properties which help:
[`OriginalRequest`][1] and [`CurrentRequest`][2]. According to Apple's
documentation, these are the same, "except when the server has responded to
the initial request with a redirect to a different URL."

This sounds perfect for us, so use these two properties to determine whether a redirect occurred.

Note that we can't use object identity, because these are 'copy' properties,
which means they'll never be the same instances, only at most a copy of
eachother. So instead compare the `AbsoluteString` property to check for
equality. As far as I'm aware, none of the other properties (request body,
headers, cookies, etc.) can be set by the server in a redirect, so there's no
need to compare those.

Fixes https://github.com/xamarin/xamarin-macios/issues/20629.

[1]: https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411572-originalrequest
[2]: https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411649-currentrequest
2024-05-28 17:35:59 +02:00
..
MessageHandlers.cs [NSUrlSessionHandler] Only update the request's RequestUri if a redirection occurred. Fixes #20629. (#20633) 2024-05-28 17:35:59 +02:00
NetworkResources.cs [NSUrlSessionHandler] Only update the request's RequestUri if a redirection occurred. Fixes #20629. (#20633) 2024-05-28 17:35:59 +02:00