Mark Title::setFragment() as @private
[lhc/web/wiklou.git] / includes / OutputPage.php
index 03ae8c9..d29ec54 100644 (file)
@@ -236,7 +236,7 @@ class OutputPage extends ContextSource {
 
        /** @var int Cache stuff. Looks like mEnableClientCache */
        protected $mSquidMaxage = 0;
-       /** @var in Upper limit on mSquidMaxage */
+       /** @var int Upper limit on mSquidMaxage */
        protected $mCdnMaxageLimit = INF;
 
        /**
@@ -273,7 +273,7 @@ class OutputPage extends ContextSource {
        private $mIndexPolicy = 'index';
        private $mFollowPolicy = 'follow';
        private $mVaryHeader = array(
-               'Accept-Encoding' => array( 'list-contains=gzip' ),
+               'Accept-Encoding' => array( 'match=gzip' ),
        );
 
        /**
@@ -1957,7 +1957,7 @@ class OutputPage extends ContextSource {
         * @since 1.27
         */
        public function lowerCdnMaxage( $maxage ) {
-               $this->mCdnMaxageLimit = $this->min( $maxage, $this->mCdnMaxageLimit );
+               $this->mCdnMaxageLimit = min( $maxage, $this->mCdnMaxageLimit );
                $this->setSquidMaxage( $this->mSquidMaxage );
        }
 
@@ -2002,14 +2002,9 @@ class OutputPage extends ContextSource {
         * @return bool
         */
        function haveCacheVaryCookies() {
-               $cookieHeader = $this->getRequest()->getHeader( 'cookie' );
-               if ( $cookieHeader === false ) {
-                       return false;
-               }
-               $cvCookies = $this->getCacheVaryCookies();
-               foreach ( $cvCookies as $cookieName ) {
-                       # Check for a simple string match, like the way squid does it
-                       if ( strpos( $cookieHeader, $cookieName ) !== false ) {
+               $request = $this->getRequest();
+               foreach ( $this->getCacheVaryCookies() as $cookieName ) {
+                       if ( $request->getCookie( $cookieName, '', '' ) !== '' ) {
                                wfDebug( __METHOD__ . ": found $cookieName\n" );
                                return true;
                        }
@@ -2022,11 +2017,9 @@ class OutputPage extends ContextSource {
         * Add an HTTP header that will influence on the cache
         *
         * @param string $header Header name
-        * @param string[]|null $option Options for X-Vary-Options. Possible options are:
-        *  - "string-contains=$XXX" varies on whether the header value as a string
-        *    contains $XXX as a substring.
-        *  - "list-contains=$XXX" varies on whether the header value as a
-        *    comma-separated list contains $XXX as one of the list items.
+        * @param string[]|null $option Options for the Key header. See
+        * https://datatracker.ietf.org/doc/draft-fielding-http-key/
+        * for the list of valid options.
         */
        public function addVaryHeader( $header, array $option = null ) {
                if ( !array_key_exists( $header, $this->mVaryHeader ) ) {
@@ -2049,16 +2042,16 @@ class OutputPage extends ContextSource {
        }
 
        /**
-        * Get a complete X-Vary-Options header
+        * Get a complete Key header
         *
         * @return string
         */
-       public function getXVO() {
+       public function getKeyHeader() {
                $cvCookies = $this->getCacheVaryCookies();
 
                $cookiesOption = array();
                foreach ( $cvCookies as $cookieName ) {
-                       $cookiesOption[] = 'string-contains=' . $cookieName;
+                       $cookiesOption[] = 'param=' . $cookieName;
                }
                $this->addVaryHeader( 'Cookie', $cookiesOption );
 
@@ -2070,13 +2063,13 @@ class OutputPage extends ContextSource {
                        }
                        $headers[] = $newheader;
                }
-               $xvo = 'X-Vary-Options: ' . implode( ',', $headers );
+               $key = 'Key: ' . implode( ',', $headers );
 
-               return $xvo;
+               return $key;
        }
 
        /**
-        * bug 21672: Add Accept-Language to Vary and XVO headers
+        * T23672: Add Accept-Language to Vary and Key headers
         * if there's no 'variant' parameter existed in GET.
         *
         * For example:
@@ -2097,14 +2090,14 @@ class OutputPage extends ContextSource {
                                if ( $variant === $lang->getCode() ) {
                                        continue;
                                } else {
-                                       $aloption[] = 'string-contains=' . $variant;
+                                       $aloption[] = 'substr=' . $variant;
 
                                        // IE and some other browsers use BCP 47 standards in
                                        // their Accept-Language header, like "zh-CN" or "zh-Hant".
                                        // We should handle these too.
                                        $variantBCP47 = wfBCP47( $variant );
                                        if ( $variantBCP47 !== $variant ) {
-                                               $aloption[] = 'string-contains=' . $variantBCP47;
+                                               $aloption[] = 'substr=' . $variantBCP47;
                                        }
                                }
                        }
@@ -2179,9 +2172,8 @@ class OutputPage extends ContextSource {
                # maintain different caches for logged-in users and non-logged in ones
                $response->header( $this->getVaryHeader() );
 
-               if ( $config->get( 'UseXVO' ) ) {
-                       # Add an X-Vary-Options header for Squid with Wikimedia patches
-                       $response->header( $this->getXVO() );
+               if ( $config->get( 'UseKeyHeader' ) ) {
+                       $response->header( $this->getKeyHeader() );
                }
 
                if ( $this->mEnableClientCache ) {
@@ -3320,22 +3312,31 @@ class OutputPage extends ContextSource {
         * @return bool
         */
        public function userCanPreview() {
-               if ( $this->getRequest()->getVal( 'action' ) != 'submit'
-                       || !$this->getRequest()->wasPosted()
-                       || !$this->getUser()->matchEditToken(
-                               $this->getRequest()->getVal( 'wpEditToken' ) )
-               ) {
+               $request = $this->getRequest();
+               if ( $request->getVal( 'action' ) !== 'submit' || !$request->wasPosted() ) {
                        return false;
                }
-               if ( !$this->getTitle()->isJsSubpage() && !$this->getTitle()->isCssSubpage() ) {
+
+               $user = $this->getUser();
+               if ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) {
                        return false;
                }
-               if ( !$this->getTitle()->isSubpageOf( $this->getUser()->getUserPage() ) ) {
+
+               $title = $this->getTitle();
+               if ( !$title->isJsSubpage() && !$title->isCssSubpage() ) {
+                       return false;
+               }
+               if ( !$title->isSubpageOf( $user->getUserPage() ) ) {
                        // Don't execute another user's CSS or JS on preview (T85855)
                        return false;
                }
 
-               return !count( $this->getTitle()->getUserPermissionsErrors( 'edit', $this->getUser() ) );
+               $errors = $title->getUserPermissionsErrors( 'edit', $user );
+               if ( count( $errors ) !== 0 ) {
+                       return false;
+               }
+
+               return true;
        }
 
        /**
@@ -3855,18 +3856,19 @@ class OutputPage extends ContextSource {
                                if ( $media == $targetMedia ) {
                                        $media = '';
                                } elseif ( preg_match( $screenMediaQueryRegex, $media ) === 1 ) {
-                                       // This regex will not attempt to understand a comma-separated media_query_list
-                                       //
-                                       // Example supported values for $media:
-                                       // 'screen', 'only screen', 'screen and (min-width: 982px)' ),
-                                       // Example NOT supported value for $media:
-                                       // '3d-glasses, screen, print and resolution > 90dpi'
-                                       //
-                                       // If it's a print request, we never want any kind of screen stylesheets
-                                       // If it's a handheld request (currently the only other choice with a switch),
-                                       // we don't want simple 'screen' but we might want screen queries that
-                                       // have a max-width or something, so we'll pass all others on and let the
-                                       // client do the query.
+                                       /* This regex will not attempt to understand a comma-separated media_query_list
+                                        *
+                                        * Example supported values for $media:
+                                        * 'screen', 'only screen', 'screen and (min-width: 982px)' ),
+                                        * Example NOT supported value for $media:
+                                        * '3d-glasses, screen, print and resolution > 90dpi'
+                                        *
+                                        * If it's a print request, we never want any kind of screen stylesheets
+                                        * If it's a handheld request (currently the only other choice with a switch),
+                                        * we don't want simple 'screen' but we might want screen queries that
+                                        * have a max-width or something, so we'll pass all others on and let the
+                                        * client do the query.
+                                        */
                                        if ( $targetMedia == 'print' || $media == 'screen' ) {
                                                return null;
                                        }