Skip to content

HTTPCookie doesn't support expiry times in the past #222

@karlr42

Description

@karlr42

I've been writing a proxy using Poco and have run into an issue handling Set-Cookie headers sent by the remote server intended to remove cookies on the browser. These Set-Cookie headers are of the form

Set-Cookie: value=; path=/; domain=example.com; expires=Thu, 30-Oct-1980 16:00:00 GMT;

i.e with an expiry date well in the past. My understanding is that setting the expiry so far in the past makes it more likely the browser will remove the cookie, obviating clock sync issues.

The problem is that Poco::Net::HTTPCookie doesn't really support such expiry times. The constructor parses the expiry time with

setMaxAge((int) ((exp.timestamp() - now)/Timestamp::resolution()));

which gives a negative maxAge for any time less than 'now'. The problem that then arises is in calling toString() on a cookie created this way with a negative maxAge. HTTPCookie::toString() will only add the "expires" attribute on a cookie if maxAge >= 0 :

if (_maxAge >= 0)
        {
            Timestamp ts;
            ts += _maxAge*Timestamp::resolution();
            result.append("; expires=");
            DateTimeFormatter::append(result, ts, DateTimeFormat::HTTP_FORMAT);
        }

This is in keeping with the HTTPCookie documentation which states that a value of 0 'deletes the cookie on the client'(presumably by setting the expiry to now and hoping that by the time the cookie gets to the browser 'now' is in the past.) and a value of -1 'causes the cookie to never expire on the client', by omitting the expires attribute entirely. However in my case where I am a proxy trying to pass through to my client a Set-Cookie header with an expiry date which produces a negative maxAge value, the expires attribute is removed entirely and the cookie is not deleted on the client as intended.

Test case here : http://pastebin.com/ar21mdL4

I would be more than happy to work on this issue and submit a patch if you give me the green light. My thinking is to refactor HTTPCookie::toString() to check maxAge for being explicitly -1, in which case no expiry information is printed, otherwise for values >=0 and <-1, add the timestamp. There may be a difficulty converting a negative maxAge into a timestamp string but I'm sure I can figure that out. I just wanted to run it by you first in case you think changing the contract and semantics of set/getMaxAge might be needed instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions