Cookie parsing

I have a self-service WCF service with an endpoint configured using WebHttpBinding that listens for HTTP requests. I need to access the cookies sent with these requests. I can get the value of the header Cookie:, but I'm stuck in the actual parsing. My implementation attempt was to use CookieContainer:

var container = new CookieContainer();
var uri = new Uri("http://localhost/");
container.SetCookies(uri, cookieHeader);
var cookies = container.GetCookies(uri).OfType<Cookie>();
foreach (var cookie in cookies)
{
    Console.WriteLine("{0} = {1}", cookie.Name, cookie.Value);
}

The problem with this code is that it CookieContainerexpects cookies to be separated by a comma ( cookieHeader="c1=v1,c2=v2"), while browsers use a semicolon ( cookieHeader="c1=v1;c2=v2") for this . Since RFC 6265 only allows semicolons to be used as a separator (earlier RFC resolution), I am a little puzzled why it CookieContainersupports only a comma. Now I'm struggling to find an alternative solution to the problem that seems pretty typical. How to handle cookies correctly? ASP.NET should be able to do this, doesn't it expose any public classes for this?

+4
source share
1 answer

Why is this not working?

, Set-Cookie: Cookie:. Set-Cookie: , , Cookie: cookie . RFC6265:

== Server -> User Agent ==

Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly
Set-Cookie: lang=en-US; Path=/; Domain=example.com

== User Agent -> Server ==

Cookie: SID=31d4d96e407aad42; lang=en-US

Set-Cookie: , , :

Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly,lang=en-US; Path=/; Domain=example.com

CookieContainer ( ), SetCookies(Uri, string) , Set-Cookie:.

ASP.Net

ASP.Net Cookie:, . . HttpListenerRequest.Cookies:

private CookieCollection ParseCookies(Uri uri, string setCookieHeader) {
    GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ParseCookies() uri:" + uri + " setCookieHeader:" + setCookieHeader);
    CookieCollection cookies = new CookieCollection();
    CookieParser parser = new CookieParser(setCookieHeader);
    for (;;) {
        Cookie cookie = parser.GetServer();
        GlobalLog.Print("HttpListenerRequest#" + ValidationHelper.HashString(this) + "::ParseCookies() CookieParser returned cookie:" + ValidationHelper.ToString(cookie));
        if (cookie==null) {
            // EOF, done.
            break;
        }
        if (cookie.Name.Length==0) {
            continue;
        }
        cookies.InternalAdd(cookie, true);
    }
    return cookies;
}

, ?

, , :

private IDictionary<string, string> GetCookieData()
{
    var cookieDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    if (!this.Headers.Cookie.Any())
    {
        return cookieDictionary;
    }

    var values = this.Headers["cookie"].First().TrimEnd(';').Split(';');
    foreach (var parts in values.Select(c => c.Split(new[] { '=' }, 2)))
    {
        var cookieName = parts[0].Trim();
        string cookieValue;

        if (parts.Length == 1)
        {
            //Cookie attribute
            cookieValue = string.Empty;
        }
        else
        {
            cookieValue = parts[1];
        }

        cookieDictionary[cookieName] = cookieValue;
    }

    return cookieDictionary;
}
+7

All Articles