Using HttpWebRequest with Cookies

Ketsuekiame 3 Tallied Votes 5K Views Share

This "FakeWebClient" will allow a C# application to send and receive cookies as part of the request. This behaviour is not available by default.

Please note that on line 35 there is a possible NullReferenceException, I managed this at a level higher but you may wish to handle it in the client.

pritaeas commented: Nice. +14
ddanbe commented: Great. +14
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details available at
<http://www.gnu.org/licenses/>
	
	public class FakeWebClient : WebClient
    {
        public CookieContainer CookieContainer { get; set; }
        public Uri Uri { get; set; }

        public FakeWebClient()
            : this(new CookieContainer())
        {
        }

        public FakeWebClient(CookieContainer cookies)
        {
            CookieContainer = cookies;
        }

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                (request as HttpWebRequest).CookieContainer = CookieContainer;
            }
            HttpWebRequest httpRequest = (HttpWebRequest)request;
            httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            return httpRequest;
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];

            if (setCookieHeader != null)
            {
                CookieCollection cookiesList = GetAllCookiesFromHeader(setCookieHeader, BaseAddress);
                if (cookiesList != null)
                    CookieContainer.Add(new Uri(BaseAddress), cookiesList);
            }
            return response;
        }

        private CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost)
        {
            CookieCollection cc = new CookieCollection();
            if (strHeader != string.Empty)
            {
                ArrayList al = ConvertCookieHeaderToArrayList(strHeader);
                cc = ConvertCookieArraysToCookieCollection(al, strHost);
            }
            return cc;
        }

        private 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 CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost)
        {
            CookieCollection cc = new CookieCollection();

            int alcount = al.Count;
            for (int i = 0; i < alcount; i++)
            {
                string strEachCook = al[i].ToString();
                string[] strEachCookParts = strEachCook.Split(';');
                int intEachCookPartsCount = strEachCookParts.Length;
                
                Cookie cookTemp = new Cookie();

                for (int j = 0; j < intEachCookPartsCount; j++)
                {
                    if (j == 0)
                    {
                        string strCNameAndCValue = strEachCookParts[j];
                        if (strCNameAndCValue != string.Empty)
                        {
                            int firstEqual = strCNameAndCValue.IndexOf("=", StringComparison.InvariantCultureIgnoreCase);
                            string firstName = strCNameAndCValue.Substring(0, firstEqual);
                            string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                            cookTemp.Name = firstName;

                            Encoding iso = Encoding.GetEncoding("utf-8");//may be utf-8
                            allValue = HttpUtility.UrlEncode(allValue, iso);

                            cookTemp.Value = allValue;
                        }
                        continue;
                    }
                    string strPNameAndPValue;
                    string[] nameValuePairTemp;
                    if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        strPNameAndPValue = strEachCookParts[j];
                        if (strPNameAndPValue != string.Empty)
                        {
                            nameValuePairTemp = strPNameAndPValue.Split('=');
                            cookTemp.Path = nameValuePairTemp[1] != string.Empty ? nameValuePairTemp[1] : "/";
                        }
                        continue;
                    }

                    if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) < 0) 
                        continue;

                    strPNameAndPValue = strEachCookParts[j];
                    
                    if (strPNameAndPValue == string.Empty) 
                        continue;
                    
                    nameValuePairTemp = strPNameAndPValue.Split('=');

                    cookTemp.Domain = nameValuePairTemp[1] != string.Empty ? nameValuePairTemp[1] : strHost;
                }

                if (cookTemp.Path == string.Empty)
                {
                    cookTemp.Path = "/";
                }
                if (cookTemp.Domain == string.Empty)
                {
                    cookTemp.Domain = strHost;
                }
                cc.Add(cookTemp);
            }
            return cc;
        }
    }
Pavel_47 0 Newbie Poster

Hello,

I've get UriFormatException on this line:
CookieContainer.Add(new Uri(BaseAddress), cookiesList);
The BaseAddress is empty, probably this is a reason ?

Thanks

pritaeas 2,194 ¯\_(ツ)_/¯ Moderator Featured Poster

probably this is a reason ?

Yes, an empty base address is not a valid URI.

Pavel_47 0 Newbie Poster

I try to use FakeWebClient this way:

            FakeWebClient client = new FakeWebClient();
            Stream stream = client.OpenRead(url);
            StreamReader sr1 = new StreamReader(stream);
            String src_URL1 = sr1.ReadToEnd();

whre url is the address of web page I try to get content.
Is my approach correct ?
Thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.