tags:

views:

1094

answers:

6

Hello,

I'm having troubles with HttpWebRequest/HttpWebResponse and cookies/CookieContainer/CookieCollection. The thing is, if the web server does not send/use a "path" in the cookie, Cookie.Path equals the path-part of the request URI instead of "/" or being empty in my application. Therefore, those cookies do not work for the whole domain, which it actually does in proper web browsers. Any ideas how to solve this issue?

Thanks in advance

A: 

That's the way cookies work. ‘Proper’ web browsers do exactly the same, as originally specified in the ancient Netscape cookies doc: http://cgi.netscape.com/newsref/std/cookie_spec.html

Web apps must effectively always set a ‘path’ (often ‘/’).

bobince
Thank you, bobince.I see, but this is a little strange to me, because this web site I was talking about which does not set a "path", somehow still seem to work across the whole domain in Internet Explorer and Firefox at least.Any ideas?
James
A: 

Oh, I did not mean to post this, only edit a previous post.

Edit: Ouch, I did edit it after all but I did not want it to be shown at the end of the list. It should be in between bobince's two posts above. Well, what can I say.. I am new here. :D

Here is the original content with minor modifications:

Thank you, bobince. I see, but this is a little strange to me, because the cookies for this web site I was talking about which does not set a "path", somehow still seem to work across the whole domain in Internet Explorer and Firefox at least. Any ideas?

Edit: Using Firefox and the AnEC Cookie Editor, I tried to have a look at the cookies which did not have a "path" set. Both of these cookies seem to have the path set to "/" in the cookie editor.

Edit 2: I'll try to give you an example of what happens in FF at least...

Response header for /login.php:

    ...
    Set-Cookie: username=user; expires=Fri, 13-Feb-2009 19:15:07 GMT
    Set-Cookie: password=password; expires=Fri, 13-Feb-2009 19:15:07 GMT
    ...

This should make the cookies work only for /login.php, right?

But please see here, the response header for /members.php (or any other file):

    ...
    Cookie: username=user; password=password
    ...

As you can see, even if no "path" was set, the cookies still work across the whole domain. Somehow, at least IE and FF (the ones I have tried), behave like this, and since I can't go around asking webmasters to follow the standard (is it?), I would really like to be able to make this exception as well, hopefully in a simple way.

Thanks in advance.

James
+1  A: 

Ah, I see what you mean. Generally what browsers really do is take the folder containing the document as the path; for ‘/login.php’ that would be ‘/’ so it would effectively work across the whole domain. ‘/potato/login.php’ would be limited to ‘/potato/’; anything with trailing path-info parts (eg. ‘/login.php/’) would not work.

In this case the Netscape spec could be considered wrong or at least misleading in claiming that path defaults to the current document path... depending on how exactly you read ‘path’ there. However the browser behaviour is consistent back as far as the original Netscape version. Netscape never were that good at writing specs...

If .NET's HttpWebRequest is really defaulting CookieContainer.Path to the entire path of the current document, I'd file a bug against it.

Unfortunately the real-world behaviour is not actually currently described in a standards document... there is RFC 2965, which does get the path thing right, but makes several other changes not representative of real-world browser behaviour, so that's not wholly reliable either. :-(

bobince
A: 

I have now tried to use HttpWebResponse.Headers.GetValues() to hopefully get a list of all the cookies, so that I can modify the "path", but there is a problem again... Here is an example from my extended WebClient class:

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = request.GetResponse();
        if (response is HttpWebResponse)
        {
            HttpWebResponse response2 = (response as HttpWebResponse);

            string[] asValues = response2.Headers.GetValues("Set-Cookie");
            if (asValues != null)
            {
                foreach (string sValue in asValues)
                {
                    MessageBox.Show("Cookie: " + sValue);
                    // code in here to modify cookie's path
                }
            }


            foreach (Cookie c in response2.Cookies)
            {
                this._Cookies.Add(c);
            }
        }
        return response;
    }

In my header example earlier, we have for example the cookie username=user; expires=Fri, 13-Feb-2009 19:15:07 GMT. I am able to show a message box with that cookie as well... Well, almost. The problem is the result is username=user; expires=Fri instead. It split it at the comma in there.

James
Erm... are you sure about this? Headers.GetValues() should not be doing any splitting or attempting to parse the cookie header. (One could argue the expires parameter should be a quoted-string to allow the comma to be parsed, but omitting quotes is unfortunately common practice.)
bobince
A: 

"If .NET's HttpWebRequest is really defaulting CookieContainer.Path to the entire path of the current document, I'd file a bug against it."

Okay, I see. Thank you so much for explaining. That is what seems to be happening. >_< And somehow I cannot use that "trick" in my previous post either, so maybe I really have to find a different solution.

James
A: 

Seems like I cannot go any further with the default cookie handler, so I got annoyed and I did it the hard way. Haha. So parsing response.Headers["Set-Cookie"] myself is my solution. Not my preferred one but it works. And I simply eliminated the problem with splitting at the wrong comma using regular expressions.

If I could give out points here, I would give you some of them, bobince, because you gave me valuable information. I would also vote up if I could (need higher rep. score), but since this behavior probably is a bug, as you mentioned, I will accept that as an answer.

Thank you. :)

James
Thank you for spotting the bug and making it googlable! :-)
bobince