Issues

ZF-7778: getCookie doesn't utilize _matchDomain (CookieJar)

Issue Type: Bug Created: 2009-09-05T09:58:32.000+0000 Last Updated: 2012-05-18T02:44:28.000+0000 Status: Closed Fix version(s): Reporter: Jason Brumwell (baxter) Assignee: Adam Lundrigan (adamlundrigan) Tags: - Zend_Http_CookieJar

  • FixForZF1.12
  • state:need-feedback
  • zf-caretaker-adamlundrigan
  • zf-crteam-review

Related issues: Attachments:

Description

When trying to retrieve a cookie using the cookieJars getCookie function it is impossible currently to match the .domain.com key associated to the cookies array. The solution I came up with was to utilize the _matchDomain , _flattenCookiesArray and _matchPath function of the cookiejar.

<pre class="highlight">
public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
    {
        if (is_string($uri)) {
            $uri = Zend_Uri::factory($uri);
        }
        
        if (! $uri instanceof Zend_Uri_Http) {
            require_once 'Zend/Http/Exception.php';
            throw new Zend_Http_Exception('Invalid URI specified');
        }

        // Get correct cookie path
        $path = $uri->getPath();
        $path = substr($path, 0, strrpos($path, '/'));
        if (! $path) $path = '/';

        $cookies = $this->_matchDomain($uri->getHost());
        $cookies = $this->_matchPath($cookies, $path);
        $cookies = $this->_flattenCookiesArray($cookies);

        foreach ($cookies as $cookie)
        {
            if ($cookie->getName() == $cookie_name)
            {
                switch ($ret_as) {
                    case self::COOKIE_OBJECT:
                        return $cookie;
                        break;

                    case self::COOKIE_STRING_ARRAY:
                    case self::COOKIE_STRING_CONCAT:
                        return $cookie->__toString();
                        break;

                    default:
                        require_once 'Zend/Http/Exception.php';
                        throw new Zend_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
                        break;
                }
            }
        }

        return false;
    }

Cheers,

Jay

Comments

Posted by Jason Brumwell (baxter) on 2009-12-29T09:15:56.000+0000

Not fixed as of 1.9.6, makes using moneybookers session api unuseable as it doesn't recognize the cookie. Haven't checked 1.10 alpha yet.

Posted by Adam Lundrigan (adamlundrigan) on 2011-11-07T17:24:18.000+0000

Could you provide an example?

The appropriateness of what you have suggested depends on what the intended purpose of getCookie is. I assumed it was for retrieving specific cookies (ie: you have to specify the exact name and domain string as set in the Set-Cookie header), while getMatchingCookies() was intended for what you are trying to accomplish above. Am I wrong in that assumption?

Posted by Jason Brumwell (baxter) on 2011-11-07T17:50:09.000+0000

Hey Adam,

The problem I ran into was when writing a class for processing Moneybookers.com payments, It was a couple of years ago now so I can't be absolutely positive, I believe the problem was that getHost returned moneybookers.com but the cookie was being stored as .moneybookers.com with a period at the begining.

Looking at the getMatchingCookies(), it looks like it may work for this as well.

Here is the resulting code that allows it to function properly:

<pre class="highlight">
public function getSessionUrl(array $data)
    {
        $client = new Zend_Http_Client(
             '<a href="https://www.moneybookers.com/app/payment.pl">https://www.moneybookers.com/app/payment.pl</a>',
             array(
                 'maxredirects' => 0,
                 'timeout'      => 30
             )
        );

        $client->setParameterPost($data);

        $client->setCookieJar(new Nexus_Http_CookieJar());

        $response = $client->request(Zend_Http_Client::POST);

        $cookie = $client->getCookieJar()->getCookie('<a>https://moneybookers.com','SESSION_ID</a>');

        if (! $cookie instanceof Zend_Http_Cookie)
        {
            throw new Default_Exception_Application('Failed to get session ID from moneybookers');
        }

        $sessionId = $cookie->getValue();

        return '<a href="https://www.moneybookers.com/app/payment.pl?sid='.$sessionId">https://moneybookers.com/app/payment.pl/…</a>;
    }

Then the getCookie extension to the cookieJar:

<pre class="highlight">
public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
    {
        if (is_string($uri)) {
            $uri = Zend_Uri::factory($uri);
        }

        if (! $uri instanceof Zend_Uri_Http) {
            require_once 'Zend/Http/Exception.php';
            throw new Zend_Http_Exception('Invalid URI specified');
        }

        // Get correct cookie path
        $path = $uri->getPath();
        $path = substr($path, 0, strrpos($path, '/'));
        if (! $path) $path = '/';

        $cookies = $this->_matchDomain($uri->getHost());
        $cookies = $this->_matchPath($cookies, $path);
        $cookies = $this->_flattenCookiesArray($cookies);

        foreach ($cookies as $cookie)
        {
            if ($cookie->getName() == $cookie_name)
            {
                switch ($ret_as) {
                    case self::COOKIE_OBJECT:
                        return $cookie;
                        break;

                    case self::COOKIE_STRING_ARRAY:
                    case self::COOKIE_STRING_CONCAT:
                        return $cookie->__toString();
                        break;

                    default:
                        require_once 'Zend/Http/Exception.php';
                        throw new Zend_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
                        break;
                }
            }
        }

        return false;
    }

Cheers,

Jay

Posted by Adam Lundrigan (adamlundrigan) on 2011-11-07T20:17:58.000+0000

Jay,

Thanks for your response. I've looked at the documentation (here), but it doesn't really spell out the exact purpose of the getCookie method. I'll see if I can find out if the intent is to have it match literal URIs or to have it do a "fuzzy" URI match like getMatchingCookies does.

From your example, it looks to me like using getMatchingCookies would work for you. The only difference would be that it returns an array of matches, and so you'd just have to pop off the first one and assign that to $cookie.

Posted by Adam Lundrigan (adamlundrigan) on 2012-05-18T02:44:28.000+0000

Closing as Won't Fix. It's unlikely this can be changed at this late stage in ZFv1's lifecycle, and a possible workaround (getMatchingCookies) exists.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts