From: Gergő Tisza Date: Tue, 8 Sep 2015 21:59:45 +0000 (-0700) Subject: Rewrite OutputPage::addVaryHeader X-Git-Tag: 1.31.0-rc.0~10065^2 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/pie.php?a=commitdiff_plain;h=6af306afa8f5e526afc2f131e2434200cd509737;p=lhc%2Fweb%2Fwiklou.git Rewrite OutputPage::addVaryHeader Rewrite OutputPage::addVaryHeader which had a very confusing structure. There is one breaking change: the $option argument was declared as array|null, but the function accepted everything and showed inconsistent behavior; e.g. $op->addVaryHeader( 'Foo', 'bar' ) resulted in 'X-Vary-Options: Foo;bar' but $op->addVaryHeader( 'Foo' ) $op->addVaryHeader( 'Foo', 'bar' ) resulted in 'X-Vary-Options: Foo'. With the patch, non-array arguments (other than null) result in an error. Change-Id: Id31d95fe27b01b00ec8a1d7a3996275fc0aacf3c --- diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 75dbd4c342..12651d72c0 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2015,17 +2015,14 @@ class OutputPage extends ContextSource { * - "list-contains=$XXX" varies on whether the header value as a * comma-separated list contains $XXX as one of the list items. */ - public function addVaryHeader( $header, $option = null ) { + public function addVaryHeader( $header, array $option = null ) { if ( !array_key_exists( $header, $this->mVaryHeader ) ) { - $this->mVaryHeader[$header] = (array)$option; - } elseif ( is_array( $option ) ) { - if ( is_array( $this->mVaryHeader[$header] ) ) { - $this->mVaryHeader[$header] = array_merge( $this->mVaryHeader[$header], $option ); - } else { - $this->mVaryHeader[$header] = $option; - } + $this->mVaryHeader[$header] = array(); + } + if ( !is_array( $option ) ) { + $option = array(); } - $this->mVaryHeader[$header] = array_unique( (array)$this->mVaryHeader[$header] ); + $this->mVaryHeader[$header] = array_unique( array_merge( $this->mVaryHeader[$header], $option ) ); } /** diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index ee2b278d4c..f0d905e599 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -259,6 +259,86 @@ class OutputPageTest extends MediaWikiTestCase { $actualHtml = implode( "\n", $links['html'] ); $this->assertEquals( $expectedHtml, $actualHtml ); } + + /** + * @dataProvider provideVaryHeaders + * @covers OutputPage::addVaryHeader + * @covers OutputPage::getVaryHeader + * @covers OutputPage::getXVO + */ + public function testVaryHeaders( $calls, $vary, $xvo ) { + // get rid of default Vary fields + $outputPage = $this->getMockBuilder( 'OutputPage' ) + ->setConstructorArgs( array( new RequestContext() ) ) + ->setMethods( array( 'getCacheVaryCookies' ) ) + ->getMock(); + $outputPage->expects( $this->any() ) + ->method( 'getCacheVaryCookies' ) + ->will( $this->returnValue( array() ) ); + TestingAccessWrapper::newFromObject( $outputPage )->mVaryHeader = array(); + + foreach ( $calls as $call ) { + call_user_func_array( array( $outputPage, 'addVaryHeader' ), $call ); + } + $this->assertEquals( $vary, $outputPage->getVaryHeader(), 'Vary:' ); + $this->assertEquals( $xvo, $outputPage->getXVO(), 'X-Vary-Options:' ); + } + + public function provideVaryHeaders() { + // note: getXVO() automatically adds Vary: Cookie + return array( + array( // single header + array( + array( 'Cookie' ), + ), + 'Vary: Cookie', + 'X-Vary-Options: Cookie', + ), + array( // non-unique headers + array( + array( 'Cookie' ), + array( 'Accept-Language' ), + array( 'Cookie' ), + ), + 'Vary: Cookie, Accept-Language', + 'X-Vary-Options: Cookie,Accept-Language', + ), + array( // two headers with single options + array( + array( 'Cookie', array( 'string-contains=phpsessid' ) ), + array( 'Accept-Language', array( 'string-contains=en' ) ), + ), + 'Vary: Cookie, Accept-Language', + 'X-Vary-Options: Cookie;string-contains=phpsessid,Accept-Language;string-contains=en', + ), + array( // one header with multiple options + array( + array( 'Cookie', array( 'string-contains=phpsessid', 'string-contains=userId' ) ), + ), + 'Vary: Cookie', + 'X-Vary-Options: Cookie;string-contains=phpsessid;string-contains=userId', + ), + array( // Duplicate option + array( + array( 'Cookie', array( 'string-contains=phpsessid' ) ), + array( 'Cookie', array( 'string-contains=phpsessid' ) ), + array( 'Accept-Language', array( 'string-contains=en', 'string-contains=en' ) ), + + + ), + 'Vary: Cookie, Accept-Language', + 'X-Vary-Options: Cookie;string-contains=phpsessid,Accept-Language;string-contains=en', + ), + array( // Same header, different options + array( + array( 'Cookie', array( 'string-contains=phpsessid' ) ), + array( 'Cookie', array( 'string-contains=userId' ) ), + ), + 'Vary: Cookie', + 'X-Vary-Options: Cookie;string-contains=phpsessid;string-contains=userId', + ), + ); + } } /**