Open aaron-yb opened 1 year ago
As tested here by @aaron-yb, when using just the native HttpClient
, the Set-Cookie
header is present in the response, but not present when performing the same request using Flurl.
This results in an empty CookieJar
when calling WithCookies
with an output parameter.
Hmm. I'm not set up with MAUI at the moment, but @aaron-yb if you could help me troubleshoot this I would appreciate it. Please try running this on iOS, based on your code sample above:
var handler = new HttpClientHandler();
handler.UserCookies = false;
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
var httpCli = new HttpClient(handler);
var flurlCli = new FlurlClient(httpCli);
var flurlResp = await flurlCli
.Request(_serviceLayerUrl)
.AppendPathSegment("Login")
.WithCookies(out var cookieJar)
.PostJsonAsync(new { CompanyDB = _companyDB, UserName = _username, Password = _password });
// what's in cookieJar?
// what's in flurlResp.Cookies?
// what's in flurlResp.Headers?
For the comments at the bottom, you could either output that info to the console or just add a breakpoint and let me know what you're seeing. I think this will be helpful in getting to the bottom of the problem. Thanks!
Hi @tmenier , apologies for the delay in getting back to you.
I get the following output on iOS:
2023-09-29 15:54:05.473476+0100 SLTest[5435:417741] cookieJar: 2023-09-29 15:54:05.473875+0100 SLTest[5435:417741] flurlResp.Cookies: 2023-09-29 15:54:05.473998+0100 SLTest[5435:417741] flurlResp.Headers 2023-09-29 15:54:05.477067+0100 SLTest[5435:417741] Server: Apache 2023-09-29 15:54:05.477190+0100 SLTest[5435:417741] Vary: Accept-Encoding 2023-09-29 15:54:05.477312+0100 SLTest[5435:417741] Date: Fri, 29 Sep 2023 14:54:00 GMT 2023-09-29 15:54:05.477409+0100 SLTest[5435:417741] Keep-Alive: timeout=5, max=100 2023-09-29 15:54:05.477496+0100 SLTest[5435:417741] Connection: Keep-Alive 2023-09-29 15:54:05.477588+0100 SLTest[5435:417741] Content-Type: application/json; odata=minimalmetadata; charset=utf-8 2023-09-29 15:54:05.477670+0100 SLTest[5435:417741] Content-Encoding: gzip 2023-09-29 15:54:05.477745+0100 SLTest[5435:417741] Content-Length: 181 2023-09-29 15:54:05.477818+0100 SLTest[5435:417741] Keep-Alive: timeout=5, max=100
and the following on Android:
[DOTNET] cookieJar: [DOTNET] ROUTEID: .node6 [DOTNET] B1SESSION: ba7e3f4c-5ed8-11ee-c000-000c2980395a-8972-7672 [DOTNET] flurlResp.Cookies: [DOTNET] B1SESSION: ba7e3f4c-5ed8-11ee-c000-000c2980395a-8972-7672 [DOTNET] ROUTEID: .node6 [DOTNET] flurlResp.Headers [DOTNET] Connection: Keep-Alive [DOTNET] Date: Fri, 29 Sep 2023 14:59:02 GMT [DOTNET] Keep-Alive: timeout=5, max=100 [DOTNET] Server: Apache [DOTNET] Set-Cookie: B1SESSION=ba7e3f4c-5ed8-11ee-c000-000c2980395a-8972-7672;HttpOnly;;Secure;SameSite=None [DOTNET] Set-Cookie: ROUTEID=.node6; path=/;Secure;SameSite=None [DOTNET] Transfer-Encoding: chunked [DOTNET] Vary: Accept-Encoding [DOTNET] X-Android-Received-Millis: 1695999546241 [DOTNET] X-Android-Response-Source: NETWORK 200 [DOTNET] X-Android-Selected-Protocol: http/1.1 [DOTNET] X-Android-Sent-Millis: 1695999542335 [DOTNET] Content-Type: application/json; odata=minimalmetadata; charset=utf-8
Interesting. Normally, when HttpClientHandler.UseCookies
is true (the default), Set-Cookie
headers are intercepted by the handler and never come through in HttpRequestMessage.Headers
. Flurl needs to see those headers in order for CookieJar
to work, so it sets that value to false. But apparently those Set-Cookie
headers still aren't coming through.
However, what I just noticed looking back at this snippet from @bgmulinari, UseCookies
is never turned off, yet apparently those headers are coming through.
It's as though UseCookies
is behaving exactly the opposite on iOS as on other platforms!
To test this theory, could you run my snippet above yet again, only remove this line entirely?
handler.UseCookies = false;
Hi @tmenier ,
Looks like you may be on to something!
Here is the output on iOS:
2023-09-30 14:59:15.240374+0100 SLTest[9230:629017] cookieJar: 2023-09-30 14:59:15.240711+0100 SLTest[9230:629017] ROUTEID: .node1 2023-09-30 14:59:15.240812+0100 SLTest[9230:629017] B1SESSION: 883a27aa-5f99-11ee-c000-000c2980395a-7456-7780 2023-09-30 14:59:15.240941+0100 SLTest[9230:629017] flurlResp.Cookies: 2023-09-30 14:59:15.241125+0100 SLTest[9230:629017] B1SESSION: 883a27aa-5f99-11ee-c000-000c2980395a-7456-7780 2023-09-30 14:59:15.241209+0100 SLTest[9230:629017] ROUTEID: .node1 2023-09-30 14:59:15.241285+0100 SLTest[9230:629017] flurlResp.Headers 2023-09-30 14:59:15.244630+0100 SLTest[9230:629017] Server: Apache 2023-09-30 14:59:15.244732+0100 SLTest[9230:629017] Vary: Accept-Encoding 2023-09-30 14:59:15.244825+0100 SLTest[9230:629017] Date: Sat, 30 Sep 2023 13:59:11 GMT 2023-09-30 14:59:15.244914+0100 SLTest[9230:629017] Keep-Alive: timeout=5, max=100 2023-09-30 14:59:15.245062+0100 SLTest[9230:629017] Connection: Keep-Alive 2023-09-30 14:59:15.245135+0100 SLTest[9230:629017] Set-Cookie: B1SESSION=883a27aa-5f99-11ee-c000-000c2980395a-7456-7780; Path=/b1s/v1; Domain= xxx.xxx.xxx; Version=0; Discard; Secure; httponly 2023-09-30 14:59:15.245234+0100 SLTest[9230:629017] Set-Cookie: ROUTEID=.node1; Path=/; Domain=xxx.xxx.xxx; Version=0; Discard; Secure 2023-09-30 14:59:15.245298+0100 SLTest[9230:629017] Content-Type: application/json; odata=minimalmetadata; charset=utf-8 2023-09-30 14:59:15.245366+0100 SLTest[9230:629017] Content-Encoding: gzip 2023-09-30 14:59:15.245423+0100 SLTest[9230:629017] Content-Length: 181 2023-09-30 14:59:15.245486+0100 SLTest[9230:629017] Keep-Alive: timeout=5, max=100
(domain outputs normally, but I have obscured it)
Here is the output on Android:
[DOTNET] ROUTEID: .node9 [DOTNET] B1SESSION: 19955720-5f99-11ee-c000-000c2980395a-6148-7472 [DOTNET] flurlResp.Cookies: [DOTNET] B1SESSION: 19955720-5f99-11ee-c000-000c2980395a-6148-7472 [DOTNET] ROUTEID: .node9 [DOTNET] flurlResp.Headers [DOTNET] Connection: Keep-Alive [DOTNET] Date: Sat, 30 Sep 2023 13:56:05 GMT [DOTNET] Keep-Alive: timeout=5, max=100 [DOTNET] Server: Apache [DOTNET] Set-Cookie: B1SESSION=19955720-5f99-11ee-c000-000c2980395a-6148-7472;HttpOnly;;Secure;SameSite=None [DOTNET] Set-Cookie: ROUTEID=.node9; path=/;Secure;SameSite=None [DOTNET] Transfer-Encoding: chunked [DOTNET] Vary: Accept-Encoding [DOTNET] X-Android-Received-Millis: 1696082170869 [DOTNET] X-Android-Response-Source: NETWORK 200 [DOTNET] X-Android-Selected-Protocol: http/1.1 [DOTNET] X-Android-Sent-Millis: 1696082165165 [DOTNET] Content-Type: application/json; odata=minimalmetadata; charset=utf-8
Wow. I think you've proven that UseCookies
behaves exactly the opposite on iOS than it does on other platforms. I'm going the leave the help-wanted
label on here in hopes that you (or someone else) can take the next steps:
Armed with that information, I'll be willing to move forward with a fix. Thanks!
Here's the default handler used on iOS platforms: https://learn.microsoft.com/en-us/dotnet/api/system.net.http.nsurlsessionhandler
And I believe this is the repo where an issue should be raised: https://github.com/xamarin/xamarin-macios
I might have time to pursue this in the near future, but if someone wants to beat me to it, by all means. :)
Hey @tmenier thanks for your replies and info- I'm having a go at working this all out, bit of a learning curve! Will see who gets there first
I have been debugging a package that implements Flurl. (Original issue here: https://github.com/bgmulinari/B1SLayer/issues/49). Have tried adjusting iOS info.plist file with NSAppTransportSecurity values.
On .NET Maui Android the following code will return session cookies:
` private async Task FlurlLoginAsync() { var loginResponse = await _serviceLayerUrl .AppendPathSegment("Login") .WithCookies(out var cookieJar) .PostJsonAsync(new { CompanyDB = _companyDB, UserName = _username, Password = _password }) .ReceiveString();
`
However when running the same from iOS, there are never any cookies. Debug output looks as following:
On iOS / Mac I get the following output:
2023-08-23 14:56:09.536898+0100 SLTest[10595:1499318] Request URL: https://url:50000/b1s/v1/Login 2023-08-23 14:56:09.537186+0100 SLTest[10595:1499318] HTTP Method: POST 2023-08-23 14:56:09.537798+0100 SLTest[10595:1499318] Response Status Code: OK 2023-08-23 14:56:09.537904+0100 SLTest[10595:1499318] Request Headers: 2023-08-23 14:56:09.538140+0100 SLTest[10595:1499318] Response Headers: 2023-08-23 14:56:09.538552+0100 SLTest[10595:1499318] Server: Apache 2023-08-23 14:56:09.538721+0100 SLTest[10595:1499318] Vary: Accept-Encoding 2023-08-23 14:56:09.540703+0100 SLTest[10595:1499318] Date: Wed, 23 Aug 2023 13:56:06 GMT 2023-08-23 14:56:09.540808+0100 SLTest[10595:1499318] Keep-Alive: timeout=5, max=100 2023-08-23 14:56:09.540898+0100 SLTest[10595:1499318] Connection: Keep-Alive 2023-08-23 14:56:09.542724+0100 SLTest[10595:1499318] Request Body: { "odata.metadata" : "https://url:50000/b1s/v1/$metadata#B1Sessions/@Element", "SessionId" : "ce6f595c-41bc-11ee-c000-000c2980395a-14548-6632", "Version" : "1000210", "SessionTimeout" : 30 } 2023-08-23 14:56:09.558334+0100 SLTest[10595:1498480] Cookies received:
On Android I get the following:
[DOTNET] Request URL: https://url:50000/b1s/v1/Login [DOTNET] HTTP Method: POST [DOTNET] Response Status Code: OK [DOTNET] Request Headers: [DOTNET] Response Headers: [DOTNET] Connection: Keep-Alive [DOTNET] Date: Wed, 23 Aug 2023 14:02:19 GMT [DOTNET] Keep-Alive: timeout=5, max=100 [DOTNET] Server: Apache [DOTNET] Set-Cookie: B1SESSION=ac58e080-41bd-11ee-c000-000c2980395a-14752-8204;HttpOnly;;Secure;SameSite=None, ROUTEID=.node8; path=/;Secure;SameSite=None [DOTNET] Vary: Accept-Encoding [DOTNET] X-Android-Received-Millis: 1692799340723 [DOTNET] X-Android-Response-Source: NETWORK 200 [DOTNET] X-Android-Selected-Protocol: http/1.1 [DOTNET] X-Android-Sent-Millis: 1692799338028 [DOTNET] Request Body: [DOTNET] { [DOTNET] "odata.metadata" : "https://url:50000/b1s/v1/$metadata#B1Sessions/@Element", [DOTNET] "SessionId" : "ac58e080-41bd-11ee-c000-000c2980395a-14752-8204", [DOTNET] "Version" : "1000210", [DOTNET] "SessionTimeout" : 30 [DOTNET] } [DOTNET] Cookies received: [DOTNET] ROUTEID: .node8 [DOTNET] B1SESSION: ac58e080-41bd-11ee-c000-000c2980395a-14752-8204 [DOTNET] Request URL: https://url:50000/b1s/v1/Login [DOTNET] HTTP Method: POST [DOTNET] Response Status Code: OK [DOTNET] Request Headers: [DOTNET] Response Headers: [DOTNET] Connection: Keep-Alive [DOTNET] Date: Wed, 23 Aug 2023 14:02:19 GMT [DOTNET] Keep-Alive: timeout=5, max=100 [DOTNET] Server: Apache [DOTNET] Set-Cookie: B1SESSION=ac567d90-41bd-11ee-c000-000c2980395a-8440-7940;HttpOnly;;Secure;SameSite=None, ROUTEID=.node7; path=/;Secure;SameSite=None [DOTNET] Vary: Accept-Encoding [DOTNET] X-Android-Received-Millis: 1692799340837 [DOTNET] X-Android-Response-Source: NETWORK 200 [DOTNET] X-Android-Selected-Protocol: http/1.1 [DOTNET] X-Android-Sent-Millis: 1692799338028 [DOTNET] Request Body: [DOTNET] { [DOTNET] "odata.metadata" : "https://url:50000/b1s/v1/$metadata#B1Sessions/@Element", [DOTNET] "SessionId" : "ac567d90-41bd-11ee-c000-000c2980395a-8440-7940", [DOTNET] "Version" : "1000210", [DOTNET] "SessionTimeout" : 30 [DOTNET] } [DOTNET] Cookies received: [DOTNET] ROUTEID: .node7 [DOTNET] B1SESSION: ac567d90-41bd-11ee-c000-000c2980395a-8440-7940