Skip to content
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

A better way to manage cookies and session for HttpClient #77668

Open
ziaulhasanhamim opened this issue Oct 31, 2022 · 5 comments
Open

A better way to manage cookies and session for HttpClient #77668

ziaulhasanhamim opened this issue Oct 31, 2022 · 5 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Net.Http
Milestone

Comments

@ziaulhasanhamim
Copy link

Background and motivation

In HttpClient there is a behavior of one cookie container per HttpClientHandler instead of one per HttpClient. This behavior looks very weird and unnecessary to me. Because the HttpClientHandler is mostly cached. One CookieContainer per HttpClient is the intended behavior for almost all use cases. I don't think the current behavior is useful in any way and have no idea why .Net took this path with HttpClient.
Although I'm not a big fan of HttpClientFactory but still when I'm using it handling cookies is complicated with it because of one cookie container per HttpClientHandler.

API Proposal

The best solution I can think of is to introduce a Session class(or even struct) that will manage the session for the requests made with it.

public class Session : IDisposable
{
    public CookieContainer CookieContainer { get; init; } = DefaultOne;

    public bool UseCookies { get; init; } = true;

    // more fields related to state management like Credentials, AllowAutoRedirect and all

    public HttpRequestHeaders DefaultRequestHeaders { get; } = new HttpRequestHeaders();

    public Uri BaseAddress { get; init; }

    // same apis for send, get, post, put, delete, patch etc like HttpClient
}

Sessions are very very useful. It helps to group certain requests. It would simplify the usage of HttpClient specially when using HttpClient as a singleton with a pooled connection.

API Usage

The session will manage the cookies, headers, and all.

var client = GetCachedClient();
using var session = new Session(client)
{
  BaseAddress = ....
};
session.DefaultHeaders.Add(....);
var res1 = await session.PostAsync(path1, req);
var res2 = await session.GetAsync(path2);

How nice is that.

Alternative Designs

An alternate way would be to add CookieContainers and all to the HttpClient itself. But Session objects are way easier to use and very simple

Risks

No response

@ziaulhasanhamim ziaulhasanhamim added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Oct 31, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Oct 31, 2022
@ghost
Copy link

ghost commented Oct 31, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

In HttpClient there is a behavior of one cookie container per HttpClientHandler instead of one per HttpClient. This behavior looks very weird and unnecessary to me. Because the HttpClientHandler is mostly cached. One CookieContainer per HttpClient is the intended behavior for almost all use cases. I don't think the current behavior is useful in any way and have no idea why .Net took this path with HttpClient.
Although I'm not a big fan of HttpClientFactory but still when I'm using it handling cookies is complicated with it because of one cookie container per HttpClientHandler.

API Proposal

The best solution I can think of is to introduce a Session class(or even struct) that will manage the session for the requests made with it.

public class Session : IDisposable
{
    public CookieContainer CookieContainer { get; init; } = DefaultOne;

    public bool UseCookies { get; init; } = true;

    // more fields related to state management like Credentials, AllowAutoRedirect and all

    public HttpRequestHeaders DefaultRequestHeaders { get; } = new HttpRequestHeaders();

    public Uri BaseAddress { get; init; }

    // same apis for send, get, post, put, delete, patch etc like HttpClient
}

Sessions are very very useful. It helps to group certain requests. It would simplify the usage of HttpClient specially when using HttpClient as a singleton with a pooled connection.

API Usage

The session will manage the cookies, headers, and all.

var client = GetCachedClient();
using var session = new Session(client)
{
  BaseAddress = ....
};
session.DefaultHeaders.Add(....);
var res1 = await session.PostAsync(path1, req);
var res2 = await session.GetAsync(path2);

How nice is that.

Alternative Designs

An alternate way would be to add CookieContainers and all to the HttpClient itself. But Session objects are way easier to use and very simple

Risks

No response

Author: ziaulhasanhamim
Assignees: -
Labels:

api-suggestion, area-System.Net.Http

Milestone: -

@ghost
Copy link

ghost commented Oct 31, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

In HttpClient there is a behavior of one cookie container per HttpClientHandler instead of one per HttpClient. This behavior looks very weird and unnecessary to me. Because the HttpClientHandler is mostly cached. One CookieContainer per HttpClient is the intended behavior for almost all use cases. I don't think the current behavior is useful in any way and have no idea why .Net took this path with HttpClient.
Although I'm not a big fan of HttpClientFactory but still when I'm using it handling cookies is complicated with it because of one cookie container per HttpClientHandler.

API Proposal

The best solution I can think of is to introduce a Session class(or even struct) that will manage the session for the requests made with it.

public class Session : IDisposable
{
    public CookieContainer CookieContainer { get; init; } = DefaultOne;

    public bool UseCookies { get; init; } = true;

    // more fields related to state management like Credentials, AllowAutoRedirect and all

    public HttpRequestHeaders DefaultRequestHeaders { get; } = new HttpRequestHeaders();

    public Uri BaseAddress { get; init; }

    // same apis for send, get, post, put, delete, patch etc like HttpClient
}

Sessions are very very useful. It helps to group certain requests. It would simplify the usage of HttpClient specially when using HttpClient as a singleton with a pooled connection.

API Usage

The session will manage the cookies, headers, and all.

var client = GetCachedClient();
using var session = new Session(client)
{
  BaseAddress = ....
};
session.DefaultHeaders.Add(....);
var res1 = await session.PostAsync(path1, req);
var res2 = await session.GetAsync(path2);

How nice is that.

Alternative Designs

An alternate way would be to add CookieContainers and all to the HttpClient itself. But Session objects are way easier to use and very simple

Risks

No response

Author: ziaulhasanhamim
Assignees: -
Labels:

api-suggestion, untriaged, area-Extensions-HttpClientFactory

Milestone: -

@ghost
Copy link

ghost commented Nov 1, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

In HttpClient there is a behavior of one cookie container per HttpClientHandler instead of one per HttpClient. This behavior looks very weird and unnecessary to me. Because the HttpClientHandler is mostly cached. One CookieContainer per HttpClient is the intended behavior for almost all use cases. I don't think the current behavior is useful in any way and have no idea why .Net took this path with HttpClient.
Although I'm not a big fan of HttpClientFactory but still when I'm using it handling cookies is complicated with it because of one cookie container per HttpClientHandler.

API Proposal

The best solution I can think of is to introduce a Session class(or even struct) that will manage the session for the requests made with it.

public class Session : IDisposable
{
    public CookieContainer CookieContainer { get; init; } = DefaultOne;

    public bool UseCookies { get; init; } = true;

    // more fields related to state management like Credentials, AllowAutoRedirect and all

    public HttpRequestHeaders DefaultRequestHeaders { get; } = new HttpRequestHeaders();

    public Uri BaseAddress { get; init; }

    // same apis for send, get, post, put, delete, patch etc like HttpClient
}

Sessions are very very useful. It helps to group certain requests. It would simplify the usage of HttpClient specially when using HttpClient as a singleton with a pooled connection.

API Usage

The session will manage the cookies, headers, and all.

var client = GetCachedClient();
using var session = new Session(client)
{
  BaseAddress = ....
};
session.DefaultHeaders.Add(....);
var res1 = await session.PostAsync(path1, req);
var res2 = await session.GetAsync(path2);

How nice is that.

Alternative Designs

An alternate way would be to add CookieContainers and all to the HttpClient itself. But Session objects are way easier to use and very simple

Risks

No response

Author: ziaulhasanhamim
Assignees: -
Labels:

api-suggestion, area-System.Net.Http, untriaged

Milestone: -

@ManickaP
Copy link
Member

Sharing some notes from @CarnaViire:

We've discussed several asks for per-request/per-session things for HttpClient, such as:

Main ask is Cookies, as currently CookieContainer is tied to HttpMessageHandler, which is very inconvenient.
Today you have to either always turn the cookies off and potentially track them manually, or to create several HttpClients and carefully manage their lifetime and usages -- there're no good workarounds.

Potential solution: add CookieContainer parameter either to HttpRequestMessage or to SendAsync overload.

Downsides: APIs like GetAsync/GetAsStringAsync etc will not get this parameter (too many overloads, and they don't expose HttpRequestMessage)

Open questions:

  • What do other languages (Java/Go/python) do with cookies?
  • What do frameworks like Angle Sharp do with cookies?
  • What do other platform handlers (WinHttp, Android, Browser) do with cookies and can we influence their behavior to align with ours?

Triage: we are aware this is a pain point for the users and want to solve this, but do it the right way, which is not as straight-forward as it might seem and needs careful design. For this, I'm moving it to future for now. We can always revisit and change the milestone.

@ManickaP ManickaP removed the untriaged New issue has not been triaged by the area owner label Nov 30, 2022
@ManickaP ManickaP added this to the Future milestone Nov 30, 2022
@ziaulhasanhamim
Copy link
Author

Potential solution: add CookieContainer parameter either to HttpRequestMessage or to SendAsync overload.

This will somehow solve the problem but this is also not that convenient

Golang uses a cookie jar. This model is pretty similar to C# and not so helpful.

As mentioned I have seen python solving this in the best way possible. They use session objects. Sessions are a way to group some requests based on common behavior regarding cookies, headers, and even middleware handlers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Net.Http
Projects
None yet
Development

No branches or pull requests

3 participants