Quellcode durchsuchen

ZF-11726: Implement RFC6265-compliant cookie string output in Zend_Http_CookieJar

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@24856 44c647ce-9c0f-0410-b52a-842ac1e357ba
adamlundrigan vor 13 Jahren
Ursprung
Commit
d152e27159

+ 10 - 1
documentation/manual/en/module_specs/Zend_Http_Cookie-Handling.xml

@@ -516,7 +516,16 @@ $cookie->match('http://www.example.com/', true, time() + (3 * 3600));
                         <acronym>HTTP</acronym> request "Cookie" header.
                     </para>
                 </listitem>
-            </itemizedlist>
+ 
+                <listitem>
+                    <para>
+                        <constant>Zend_Http_CookieJar::COOKIE_STRING_CONCAT_STRICT</constant>: Similar to
+                        COOKIE_STRING_CONCAT, but follows a strict implementation of RFC6265.  In this mode,
+                        a single space character always follows the semicolon separator between cookies, and 
+                        the semicolon separator is stripped from the end of the cookie string.
+                    </para>
+                </listitem>
+           </itemizedlist>
         </para>
 
         <para>

+ 25 - 2
library/Zend/Http/CookieJar.php

@@ -78,6 +78,13 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
     const COOKIE_STRING_CONCAT = 2;
 
     /**
+     * Return all cookies as one long string (strict mode)
+     *  - Single space after the semi-colon separating each cookie
+     *  - Remove trailing semi-colon, if any
+     */
+    const COOKIE_STRING_CONCAT_STRICT = 3;
+
+    /**
      * Array storing cookies
      *
      * Cookies are stored according to domain and path:
@@ -173,6 +180,9 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
     public function getAllCookies($ret_as = self::COOKIE_OBJECT)
     {
         $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
+        if($ret_as == self::COOKIE_STRING_CONCAT_STRICT) {
+            $cookies = rtrim(trim($cookies), ';');
+        }
         return $cookies;
     }
 
@@ -209,6 +219,9 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
 
         // Now, use self::_flattenCookiesArray again - only to convert to the return format ;)
         $ret = $this->_flattenCookiesArray($ret, $ret_as);
+        if($ret_as == self::COOKIE_STRING_CONCAT_STRICT) {
+            $ret = rtrim(trim($ret), ';');
+        }
 
         return $ret;
     }
@@ -245,6 +258,10 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
                     return $cookie;
                     break;
 
+                case self::COOKIE_STRING_CONCAT_STRICT:
+                    return rtrim(trim($cookie->__toString()), ';');
+                    break;
+
                 case self::COOKIE_STRING_ARRAY:
                 case self::COOKIE_STRING_CONCAT:
                     return $cookie->__toString();
@@ -270,9 +287,12 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
      */
     protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
         if (is_array($ptr)) {
-            $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
+            $ret = ($ret_as == self::COOKIE_STRING_CONCAT || $ret_as == self::COOKIE_STRING_CONCAT_STRICT) ? '' : array();
             foreach ($ptr as $item) {
-                if ($ret_as == self::COOKIE_STRING_CONCAT) {
+                if ($ret_as == self::COOKIE_STRING_CONCAT_STRICT) {
+                    $postfix_combine = (!is_array($item) ? ' ' : '');
+                    $ret .= $this->_flattenCookiesArray($item, $ret_as) . $postfix_combine;
+                } elseif ($ret_as == self::COOKIE_STRING_CONCAT) {
                     $ret .= $this->_flattenCookiesArray($item, $ret_as);
                 } else {
                     $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as));
@@ -285,6 +305,9 @@ class Zend_Http_CookieJar implements Countable, IteratorAggregate
                     return array($ptr->__toString());
                     break;
 
+                case self::COOKIE_STRING_CONCAT_STRICT:
+                    // break intentionally omitted
+
                 case self::COOKIE_STRING_CONCAT:
                     return $ptr->__toString();
                     break;

+ 31 - 0
tests/Zend/Http/CookieJarTest.php

@@ -167,6 +167,30 @@ class Zend_Http_CookieJarTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * Test we can get all cookies as a concatenated string
+     * @group ZF-11726
+     */
+    public function testGetAllCookiesAsConcatStrictMode()
+    {
+        $jar = new Zend_Http_CookieJar();
+
+        $cookies = array(
+            'name=Arthur; domain=camelot.gov.uk',
+            'quest=holy+grail; domain=forest.euwing.com',
+            'swallow=african; domain=bridge-of-death.net'
+        );
+
+        foreach ($cookies as $cookie) {
+            $jar->addCookie($cookie);
+        }
+
+        $expected = 'name=Arthur; quest=holy+grail; swallow=african';
+        $real = $jar->getAllCookies(Zend_Http_CookieJar::COOKIE_STRING_CONCAT_STRICT);
+
+        $this->assertEquals($expected, $real, 'Concatenated string is not as expected');
+    }
+
+    /**
      * Test we can get a single cookie as an object
      *
      */
@@ -382,6 +406,13 @@ class Zend_Http_CookieJarTest extends PHPUnit_Framework_TestCase
 
         $cookies = $jar->getMatchingCookies('http://www.foo.com/path/file.txt', true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT);
         $this->assertType('string', $cookies, '$cookies is expected to be a string');
+        $expected = 'foo1=bar1;foo2=bar2;foo4=bar4;foo7=bar7;';
+        $this->assertEquals($expected, $cookies, 'Concatenated string is not as expected');
+
+        $cookies = $jar->getMatchingCookies('http://www.foo.com/path/file.txt', true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT_STRICT);
+        $this->assertType('string', $cookies, '$cookies is expected to be a string');
+        $expected = 'foo1=bar1; foo2=bar2; foo4=bar4; foo7=bar7';
+        $this->assertEquals($expected, $cookies, 'Concatenated string is not as expected');
     }
 
     /**