Search code examples
c#cookieshttpwebrequestcookiecontainer

How to share cookies between domain.com and www.domain.com?


I'm using HttpWebRequest to download data from the website, and I noticed a bug related to the cookies. When you get the data from domain.com, and that website redirects to www.domain.com, which sends a cookie, that cookie isn't shared with domain.com. This causes some nasty bugs in my app.

I know that www.domain.com is not necessary the same website as domain.com, but I believe that in this case the benefits will outweigh any associated risks.

Is there any easy way to automatically apply cookies from domain.com to www.domain.com and vice verse?


Solution

  • Here's what I did:

        class DomainComparer : StringComparer
        {
            public override int Compare(string x, string y)
            {
                if (x == null || y == null)
                {
                    return StringComparer.OrdinalIgnoreCase.Compare(x, y);
                }
                if (x.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
                {
                    x = x.Substring(4);
                }
                if (y.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
                {
                    y = y.Substring(4);
                }
                return StringComparer.OrdinalIgnoreCase.Compare(x, y);
            }
    
            public override bool Equals(string x, string y)
            {
                return Compare(x, y) == 0;
            }
    
            public override int GetHashCode(string obj)
            {
                if (obj.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
                {
                    obj = obj.Substring(4);
                }
                return StringComparer.OrdinalIgnoreCase.GetHashCode(obj);
            }
        }
    
        /// <summary>
        /// this is a hackfix for microsoft bug, where cookies are not shared between www.domain.com and domain.com
        /// </summary>
        /// <param name="cc"></param>
        static void ImproveCookieContainer(CookieContainer cc)
        {
            Hashtable table = (Hashtable)cc.GetType().InvokeMember(
                "m_domainTable",
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance,
                null, cc, new object[] { });
            var comparerPreperty = table.GetType().GetField("_keycomparer", 
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance);
            if (comparerPreperty != null)
            {
                comparerPreperty.SetValue(table, new DomainComparer());
            }
        }