Recently I had a mystery with HttpOnly cookies in WP7. It seemed like they disappeared magically from the response header in a httpWebReqeust.
Using this code firing at some one issuing a HttpCookie:
CookieContainer cookieJar = new CookieContainer();
private void FireRequest()
{
var request = HttpWebRequest.Create(new Uri("http://www.google.se")) as HttpWebRequest;
request.Method = "GET";
request.CookieContainer = cookieJar;
request.BeginGetResponse(ar =>
{
HttpWebRequest req2 = (HttpWebRequest)ar.AsyncState;
var response = (HttpWebResponse)req2.EndGetResponse(ar);
int numVisibleCookies = response.Cookies.Count;
}, request);
}
Inspecting the response.Cookies.Count would only reveal 1 cookie, eventhou my Fiddler capture suggested two! It was clear to me that the HttpOnly attribute on the second cookie, made it invisible!
Headers captured with Fiddler (see instructions here: http://phone7.wordpress.com/2010/10/17/fiddler-and-wp7-emulator-working/)
HTTP/1.1 200 OK
Date: Wed, 28 Sep 2011 07:18:28 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Set-Cookie: PREF=ID=730e57a63c8afc7d:FF=0:TM=1317194308:LM=1317194308:S=OjVtq8VJG4RUFtHq; expires=Fri, 27-Sep-2013 07:18:28 GMT; path=/; domain=.google.se
Set-Cookie: NID=51=kXqGUUCG_z11Gu2XWpfDtvYJ6B1YB4r4tcYVH2NoZ90GqkZdAdHz9-DhRv5KcxrMmjmWF6efjMedinc3xSh5RwI8ffzmkdBrSJIpQ4QlDsX5Wsb8yB9UbgxhCQ6lLhmY; expires=Thu, 29-Mar-2012 07:18:28 GMT; path=/; domain=.google.se; HttpOnly
Age: 0
But looking at response.Cookies.count only shows one cookie!
At first I was sure the WP7 framework actually filtered out the header and threw it away. However, it dawned on me that the CookieContainer actually protected the Cookie not letting me see it! So, updating the code slightly to produce two calls and then inspect the headers again:
CookieContainer cookieJar = new CookieContainer();
int count = 0;
private void FireRequest()
{
var request = HttpWebRequest.Create(new Uri("http://www.google.se")) as HttpWebRequest;
request.Method = "GET";
request.CookieContainer = cookieJar;
request.BeginGetResponse(ar =>
{
HttpWebRequest req2 = (HttpWebRequest)ar.AsyncState;
var response = (HttpWebResponse)req2.EndGetResponse(ar);
int numVisibleCookies = response.Cookies.Count;
// Now Fire again and inspect cookie.
count++;
if (count < 2)
{
// Now just fire another request to inspect headers
FireRequest();
}
}, request);
}
Inspecting the captured headers in Fiddler, shows us that httpWebRequest actually sends two cookies in the second request… AS LONG AS you make sure to hold on to your CookieContainer and re use the same one on the second call!
First request: Headers Received: (removed noise)
HTTP/1.1 200 OK
Set-Cookie: PREF=ID=730e57a63c8afc7d:FF=0:TM=1317194308:LM=1317194308:S=OjVtq8VJG4RUFtHq; expires=Fri, 27-Sep-2013 07:18:28 GMT; path=/; domain=.google.se
Set-Cookie: NID=51=kXqGUUCG_z11Gu2XWpfDtvYJ6B1YB4r4tcYVH2NoZ90GqkZdAdHz9-DhRv5KcxrMmjmWF6efjMedinc3xSh5RwI8ffzmkdBrSJIpQ4QlDsX5Wsb8yB9UbgxhCQ6lLhmY; expires=Thu, 29-Mar-2012 07:18:28 GMT; path=/; domain=.google.se; HttpOnly
Second request, Headers sent:
GET http://www.google.se/ HTTP/1.1
Accept: */*
Referer: file:///Applications/Install/4AC5F2A5-C382-41C9-ADD0-1F5E368D541F/Install/
Accept-Encoding: identity
Cookie: PREF=ID=730e57a63c8afc7d:FF=0:TM=1317194308:LM=1317194308:S=OjVtq8VJG4RUFtHq; NID=51=kXqGUUCG_z11Gu2XWpfDtvYJ6B1YB4r4tcYVH2NoZ90GqkZdAdHz9-DhRv5KcxrMmjmWF6efjMedinc3xSh5RwI8ffzmkdBrSJIpQ4QlDsX5Wsb8yB9UbgxhCQ6lLhmY
User-Agent: NativeHost
Host: www.google.se
Proxy-Connection: Keep-Alive
And there was the proof that eventhou we could not see the cookies in the response.Cookies collection, they are in the container, and actually got sent on the second request!