Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpWebResponse.Cookies empty despite Set-Cookie Header (no-redirect)

I'm struggling to figure out what is wrong here. I'm sending login information, I can see the Set-Cookie in the Header with the correct value, but the Cookies collection is not getting filled.

This is HTTPS, the login auto-redirects, but I disabled it with AllowAutoRedirect=false to try to troubleshoot this issue.

In this screenshot, you can easily see the debug information and that the cookie should be getting set. I am setting my httpWebRequest.Cookie to a new CookieCollection.

Right click and select view image to see full-size.

HttpWebRequest httpRequest; CookieContainer reqCookies = new CookieContainer(); string url = "https://example.com"; string[] email = user.Split('@'); email[0] = System.Web.HttpUtility.UrlEncode(email[0]); user = email[0] + "@" + email[1]; pass = System.Web.HttpUtility.UrlEncode(pass);  string postData = "email=" + user + "&password=" + pass; byte[] byteData = Encoding.UTF8.GetBytes(postData);  httpRequest = (HttpWebRequest)WebRequest.Create(url); httpRequest.Method = "POST"; httpRequest.Referer = url; httpRequest.CookieContainer = reqCookies; httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1003.1 Safari/535.19"; httpRequest.Accept = "text/html, application/xhtml+xml, */*"; httpRequest.ContentType = "application/x-www-form-urlencoded"; httpRequest.ContentLength = byteData.Length; using (Stream postStream = httpRequest.GetRequestStream()) {     postStream.Write(byteData, 0, byteData.Length);     postStream.Close(); }  httpRequest.AllowAutoRedirect = false; HttpWebResponse b = (HttpWebResponse)httpRequest.GetResponse(); 

Tried the exact same code connecting to http://www.yahoo.com and the cookies are put into my collection... Argh...

Here is the Set-Cookie Header value:

s=541E2101-B768-45C8-B814-34A00525E50F; Domain=example.com; Path=/; Version=1

like image 998
Brad Avatar asked Feb 27 '13 03:02

Brad


2 Answers

UPDATE five years later, someone actually mentioned the correct way to do it: setting up the CookieContainer correctly in the first place and letting it handle everything. Please refer to Sam's solution further down.

I've found that issue as well, when reading Cookies in C# that were created by a C# ASP.NET app... ;)

Not sure if it has to do with it, but I found that the two Cookies that are set in my case are written in a single Set-Cookie header, with the cookie payload separated by commas. So I adapted AppDeveloper's solution to deal with this multiple-cookie issue, as well as fixing the name/value thing I mentioned in the comments.

private static void fixCookies(HttpWebRequest request, HttpWebResponse response)  {     for (int i = 0; i < response.Headers.Count; i++)     {         string name = response.Headers.GetKey(i);         if (name != "Set-Cookie")             continue;         string value = response.Headers.Get(i);         foreach (var singleCookie in value.Split(','))         {             Match match = Regex.Match(singleCookie, "(.+?)=(.+?);");             if (match.Captures.Count == 0)                 continue;             response.Cookies.Add(                 new Cookie(                     match.Groups[1].ToString(),                      match.Groups[2].ToString(),                      "/",                      request.Host.Split(':')[0]));         }     } } 
like image 179
Nicolas78 Avatar answered Oct 04 '22 09:10

Nicolas78


The Cookies property will be null unless the CookieContainer is set on the HttpWebRequest. So the proper way to do this is to set the CookieContainer member before retrieving the response:

var request = (HttpWebRequest)HttpWebRequest.Create(..); request.CookieContainer = new CookieContainer();  var response = request.GetResponse(); // ..response.Cookies will now contain the cookies sent back by the server. 

You don't need to manually parse Set-Cookie.

See the documentation for more information.

like image 23
Sam Avatar answered Oct 04 '22 10:10

Sam