Mapping Header cookie string to CookieCollection and vice versa

后端 未结 3 815
暖寄归人
暖寄归人 2021-02-05 12:47

Consider a web response with this header:

Set-Cookie: sample=testCookie; Domain=.sample.com; Expires=Tue, 25-Jan-2012 00:49:29 GMT; Path=/

this

相关标签:
3条回答
  • 2021-02-05 13:11

    I know that this has already been answered, but you might like to use this code: http://snipplr.com/view/4427/

    I'm posting it here in case the link goes down at some point:

    public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost)
    {
        ArrayList al = new ArrayList();
        CookieCollection cc = new CookieCollection();
        if (strHeader != string.Empty)
        {
            al = ConvertCookieHeaderToArrayList(strHeader);
            cc = ConvertCookieArraysToCookieCollection(al, strHost);
        }
        return cc;
    }
    
    
    private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader)
    {
        strCookHeader = strCookHeader.Replace("\r", "");
        strCookHeader = strCookHeader.Replace("\n", "");
        string[] strCookTemp = strCookHeader.Split(',');
        ArrayList al = new ArrayList();
        int i = 0;
        int n = strCookTemp.Length;
        while (i < n)
        {
            if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0)
            {
                al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]);
                i = i + 1;
            }
            else
            {
                al.Add(strCookTemp[i]);
            }
            i = i + 1;
        }
        return al;
    }
    
    
    private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost)
    {
        CookieCollection cc = new CookieCollection();
    
        int alcount = al.Count;
        string strEachCook;
        string[] strEachCookParts;
        for (int i = 0; i < alcount; i++)
        {
            strEachCook = al[i].ToString();
            strEachCookParts = strEachCook.Split(';');
            int intEachCookPartsCount = strEachCookParts.Length;
            string strCNameAndCValue = string.Empty;
            string strPNameAndPValue = string.Empty;
            string strDNameAndDValue = string.Empty;
            string[] NameValuePairTemp;
            Cookie cookTemp = new Cookie();
    
            for (int j = 0; j < intEachCookPartsCount; j++)
            {
                if (j == 0)
                {
                    strCNameAndCValue = strEachCookParts[j];
                    if (strCNameAndCValue != string.Empty)
                    {
                        int firstEqual = strCNameAndCValue.IndexOf("=");
                        string firstName = strCNameAndCValue.Substring(0, firstEqual);
                        string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                        cookTemp.Name = firstName;
                        cookTemp.Value = allValue;
                    }
                    continue;
                }
                if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    strPNameAndPValue = strEachCookParts[j];
                    if (strPNameAndPValue != string.Empty)
                    {
                        NameValuePairTemp = strPNameAndPValue.Split('=');
                        if (NameValuePairTemp[1] != string.Empty)
                        {
                            cookTemp.Path = NameValuePairTemp[1];
                        }
                        else
                        {
                            cookTemp.Path = "/";
                        }
                    }
                    continue;
                }
    
                if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    strPNameAndPValue = strEachCookParts[j];
                    if (strPNameAndPValue != string.Empty)
                    {
                        NameValuePairTemp = strPNameAndPValue.Split('=');
    
                        if (NameValuePairTemp[1] != string.Empty)
                        {
                            cookTemp.Domain = NameValuePairTemp[1];
                        }
                        else
                        {
                            cookTemp.Domain = strHost;
                        }
                    }
                    continue;
                }
            }
    
            if (cookTemp.Path == string.Empty)
            {
                cookTemp.Path = "/";
            }
            if (cookTemp.Domain == string.Empty)
            {
                cookTemp.Domain = strHost;
            }
            cc.Add(cookTemp);
        }
        return cc;
    }
    

    This code works better than Microsoft's own cookie parser and this is really what the official cookie parser should be doing. I don't have any clue why Microsoft hasn't fixed this yet since it's a very common issue. It will read in cookies that are comma separated and correctly parse all parts of each cookie including name, expiration, path, value, and domain.

    0 讨论(0)
  • 2021-02-05 13:12

    I think you are looking for CookieContainer. See SetCookies method.

    0 讨论(0)
  • 2021-02-05 13:28

    Here is my extension class I use to do this.

    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Net;
    using System.Text.RegularExpressions;
    using System.Web;
    
    namespace YourProjectName.Extensions
    {
         public static class HttpCookieExtension
        {
             static Regex rxCookieParts = new Regex(@"(?<name>.*?)\=(?<value>.*?)\;|(?<name>\bsecure\b|\bhttponly\b)", RegexOptions.Compiled |RegexOptions.Singleline|RegexOptions.IgnoreCase);
             static Regex rxRemoveCommaFromDate = new Regex(@"\bexpires\b\=.*?(\;|$)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
             public static bool GetHttpCookies(this NameValueCollection collection, int index , out List<HttpCookie> cookies)
             {
                 cookies = new List<HttpCookie>();
    
                 if (collection.AllKeys[index].ToLower() != "set-cookie") return false;
                 try
                 {
    
                     string rawcookieString = rxRemoveCommaFromDate.Replace(collection[index],  new MatchEvaluator(RemoveComma));
    
                     string[] rawCookies = rawcookieString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    
                     foreach (var rawCookie in rawCookies)
                     {
                        cookies.Add(rawCookie.ToHttpCookie());
                     }
                     return true;
                 }
                 catch (Exception)
                 {
    
                     return false;
                 }
             }
    
    
             public static bool GetHttpCookiesFromHeader(this string cookieHeader, out CookieCollection cookies)
             {
                 cookies = new CookieCollection();
    
    
                 try
                 {
    
                     string rawcookieString = rxRemoveCommaFromDate.Replace(cookieHeader, new MatchEvaluator(RemoveComma));
    
                     string[] rawCookies = rawcookieString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
    
                     if (rawCookies.Length == 0)
                     {
                         cookies.Add(rawcookieString.ToCookie());
                     }
                     else
                     {
                        foreach (var rawCookie in rawCookies)
                        {
                            cookies.Add(rawCookie.ToCookie());
                        }
                     }
    
                     return true;
                 }
                 catch (Exception)
                 {
                     throw;
                 }
             }
    
    
    
    
             public static Cookie ToCookie(this string rawCookie)
             {
    
                 if (!rawCookie.EndsWith(";")) rawCookie += ";";
    
                 MatchCollection maches = rxCookieParts.Matches(rawCookie);
    
                 Cookie cookie = new Cookie(maches[0].Groups["name"].Value.Trim(), maches[0].Groups["value"].Value.Trim());
    
                 for (int i = 1; i < maches.Count; i++)
                 {
                     switch (maches[i].Groups["name"].Value.ToLower().Trim())
                     {
                         case "domain":
                             cookie.Domain = maches[i].Groups["value"].Value;
                             break;
                         case "expires":
    
                             DateTime dt;
    
                             if (DateTime.TryParse(maches[i].Groups["value"].Value, out dt))
                             {
                                 cookie.Expires = dt;
                             }
                             else
                             {
                                 cookie.Expires = DateTime.Now.AddDays(2);
                             }
                             break;
                         case "path":
                             cookie.Path = maches[i].Groups["value"].Value;
                             break;
                         case "secure":
                             cookie.Secure = true;
                             break;
                         case "httponly":
                             cookie.HttpOnly = true;
                             break;
                     }
                 }
                 return cookie;
    
    
             }
    
             public static HttpCookie ToHttpCookie(this string rawCookie)
             {
                 MatchCollection maches = rxCookieParts.Matches(rawCookie);
    
                 HttpCookie cookie = new HttpCookie(maches[0].Groups["name"].Value, maches[0].Groups["value"].Value);
    
                 for (int i = 1; i < maches.Count; i++)
                 {
                     switch (maches[i].Groups["name"].Value.ToLower().Trim())
                     {
                         case "domain":
                             cookie.Domain = maches[i].Groups["value"].Value;
                             break;
                         case "expires":
    
                             DateTime dt;
    
                             if (DateTime.TryParse(maches[i].Groups["value"].Value, out dt))
                             {
                                 cookie.Expires = dt;
                             }
                             else
                             {
                                 cookie.Expires = DateTime.Now.AddDays(2);
                             }
                             break;
                         case "path":
                             cookie.Path = maches[i].Groups["value"].Value;
                             break;
                         case "secure":
                             cookie.Secure = true;
                             break;
                         case "httponly":
                             cookie.HttpOnly = true;
                             break;
                     }
                 }
                 return cookie;
             }
    
             private static KeyValuePair<string, string> SplitToPair(this string input)
             {
                string[]  parts= input.Split(new char[] {'='},StringSplitOptions.RemoveEmptyEntries);
                return new KeyValuePair<string, string>(parts[0],parts[1]);
             }
    
             private static string RemoveComma(Match match)
             {
                 return match.Value.Replace(',', ' ');
             }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题