Skip to content

Conversation

@mandel-macaque
Copy link
Contributor

There are two important things to look at this:

  1. That we do set the cookies that are present in the CookieContainer in
    the request. That is, we need to set Cookie headers for all of them.
  2. That if we receive a Set-Cookie from the server, the CookieContainer
    gets correctly updated else we will have issues since we do not respect
    the data sent from the server side.

Tests show both that we are setting the Cookie header and that we honour
the Set-Cookie header.

Fixes: #5665

There are two important things to look at this:

1. That we do set the cookies that are present in the CookieContainer in
the request. That is, we need to set Cookie headers for all of them.
2. That if we receive a Set-Cookie from the server, the CookieContainer
gets correctly updated else we will have issues since we do not respect
the data sent from the server side.

Tests show both that we are setting the Cookie header and that we honour
the Set-Cookie header.

Fixes: dotnet#5665
@monojenkins
Copy link
Collaborator

Build failure
Build succeeded
API Diff (from stable)
ℹ️ API Diff (from PR only) (please review changes)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 86 tests passed.

Failed tests

  • monotouch-test/watchOS 32-bits - simulator/Debug: Crashed

Copy link
Contributor

@chamons chamons left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the test. I think you left in debug spam.

{
var uri = new Uri (url.AbsoluteString);
if (sessionHandler.cookieContainer != null && cookies.Length > 0)
lock (sessionHandler.inflightRequestsLock) { // esure we lock when writing to the collection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: type eNsure

Copy link
Contributor

@spouliot spouliot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after CWL are removed

if (cookies != null && cookies.Count > 0) {
foreach (var cookie in cookies) {
Console.WriteLine ($"Adding cookie: {cookie.ToString ()} ");
request.Headers.TryAddWithoutValidation (Cookie, cookie.ToString ()); // as per docs: Returns a string representation of this Cookie object that is suitable for including in a HTTP Cookie: request header.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure the standard allows having multiple Cookie headers.
I think the recommendation is to "join" all cookies into a single Cookie header using the ; character.

https://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to use GetCookieHeader instead of GetCookies.

It looks that this is the approach that AndroidClientHandler.cs takes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a very good point. And I won't have to deal with the specific Header details!

}
}

public CookieContainer CookieContainer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AndroidClientHandler.cs also has a UseCookies property inherited from HttpClientHandler. Interestingly enough, NSUrlSessionHandler inherits from HttpMessageHandler instead :-?

I'd say the property is useful since it allows you to opt-out from this feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can implement such a property BUT we should do it in a diff PR. The issue is that we also have to deal with the fact that iOS has its own 'CookieContainer' so if we set the property, we have to make sure that we do not use the native CookieContainer or the managed one. I'd like to keep the PR small since this code is complicated. Added an issue that I'll fix once we land this: #7659

1. Remove poor mans debugger CWL.
2. Fix manuel typos.
3. Get the cookies header directly from the cookie container. Less
looping and easier code.
Assert.IsNull (ex, "Exception");
Assert.IsNotNull (managedCookieResult, "Managed cookies result");
Assert.IsNotNull (nativeCookieResult, "Native cookies result");
Assert.AreEqual (managedCookieResult, nativeCookieResult, "Cookies");
Copy link
Contributor

@cosminstirbu cosminstirbu Dec 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My two cents - we should have an assertion on the generated NSUrlRequest that verifies the cookie header (name and value). This could be done by injecting the underlying NSUrlSession and capturing the parameter passed to CreateDataTask

Not sure if the current structure of the code allows this verification.

Copy link
Contributor

@cosminstirbu cosminstirbu Dec 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or better yet - this test might be a better candidate for an integration test that uses some sort of test server - either in process (e.g. https://github.com/WireMock-Net/WireMock.Net) or a live server (e.g. https://httpbin.org/get)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is ensuring that the same cookies are sent when using the managed handler and the unmanaged. The request from httpbin.org returns a dictionary of cookies + values. So if they are equal, we should be fine.

Assert.IsNotNull (nativeCookieResult, "Native cookies result");
var cookiesFromServer = cookieContainer.GetCookies (new Uri (url));
Assert.AreEqual (1, cookiesFromServer.Count, "Cookies received from server.");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would worth checking the name and the value of the actual cookie as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid point. Merge and will update the test :)

@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

Build succeeded

@monojenkins
Copy link
Collaborator

Build failure
Build succeeded
API Diff (from stable)
ℹ️ API Diff (from PR only) (please review changes)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 86 tests passed.

Failed tests

  • monotouch-test/watchOS 32-bits - simulator/Debug: Crashed

@mandel-macaque
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CookieContainer support in NSUrlSessionHandler

5 participants