r69776 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r69775‎ | r69776 | r69777 >
Date:07:17, 23 July 2010
Author:tstarling
Status:ok (Comments)
Tags:
Comment:
Rewrote r69339 etc. to clean up API cache header handling.

* Introduced a "cache mode" concept to simplify the header generation code, and to avoid odd results when conflicting cache header requests are received from submodules, or at least to formalise the handling of such cases.
* Made the cache mode private by default, so that code written in ignorance of caching tends to be safe. If different query modules are used in a single request, private caching is preferred over public caching.
* Removed the "must-revalidate" option from all CC headers, this is really specific to page views with a hacked squid in front, I don't think it's applicable here.
* Made the watchlist module private. This is really the definition of private data. There's nothing in the HTTP spec that says the URL for a CC:public request is private and can't be leaked. CC:private provides protection against unknown proxy behaviour.
* In ApiQueryAllmessages: avoid calling $wgLang->getCode() to check if it's necessary to make a new $wgLang when lang= is specified, since this is the only thing that unstubs $wgUser.
* Removed "FIXME: should this check $user instead of $wgUser?" Answer is no.
Modified paths:
  • /trunk/phase3/includes/api/ApiBase.php (modified) (history)
  • /trunk/phase3/includes/api/ApiExpandTemplates.php (modified) (history)
  • /trunk/phase3/includes/api/ApiLogout.php (modified) (history)
  • /trunk/phase3/includes/api/ApiMain.php (modified) (history)
  • /trunk/phase3/includes/api/ApiOpenSearch.php (modified) (history)
  • /trunk/phase3/includes/api/ApiParse.php (modified) (history)
  • /trunk/phase3/includes/api/ApiPatrol.php (modified) (history)
  • /trunk/phase3/includes/api/ApiPurge.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuery.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllCategories.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllLinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllUsers.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllimages.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllmessages.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryAllpages.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryBacklinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryBase.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryBlocks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryCategories.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryCategoryInfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryCategoryMembers.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryDeletedrevs.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryDuplicateFiles.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryExtLinksUsage.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryExternalLinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryFilearchive.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryIWBacklinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryIWLinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryImageInfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryImages.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryInfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryLangLinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryLinks.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryLogEvents.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryProtectedTitles.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryRandom.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryRecentChanges.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryRevisions.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuerySearch.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuerySiteinfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryTags.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryUserContributions.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryUserInfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryUsers.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryWatchlist.php (modified) (history)
  • /trunk/phase3/includes/api/ApiWatch.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiQueryAllLinks.php
@@ -43,6 +43,10 @@
4444 $this->run();
4545 }
4646
 47+ public function getCacheMode( $params ) {
 48+ return 'public';
 49+ }
 50+
4751 public function executeGenerator( $resultPageSet ) {
4852 $this->run( $resultPageSet );
4953 }
@@ -221,4 +225,4 @@
222226 public function getVersion() {
223227 return __CLASS__ . ': $Id$';
224228 }
225 -}
\ No newline at end of file
 229+}
Index: trunk/phase3/includes/api/ApiQueryRecentChanges.php
@@ -143,7 +143,6 @@
144144 // Check permissions
145145 global $wgUser;
146146 if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) {
147 - $this->getMain()->setVaryCookie();
148147 if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) {
149148 $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
150149 }
@@ -376,7 +375,6 @@
377376
378377 if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
379378 global $wgUser;
380 - $this->getMain()->setVaryCookie();
381379 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title );
382380 }
383381
@@ -413,9 +411,6 @@
414412 }
415413
416414 if ( !is_null( $this->token ) ) {
417 - // Don't cache tokens
418 - $this->getMain()->setCachePrivate();
419 -
420415 $tokenFunctions = $this->getTokenFunctions();
421416 foreach ( $this->token as $t ) {
422417 $val = call_user_func( $tokenFunctions[$t], $row->rc_cur_id,
@@ -449,6 +444,24 @@
450445 }
451446 }
452447
 448+ public function getCacheMode( $params ) {
 449+ if ( isset( $params['show'] ) ) {
 450+ foreach ( $params['show'] as $show ) {
 451+ if ( $show === 'patrolled' || $show === '!patrolled' ) {
 452+ return 'private';
 453+ }
 454+ }
 455+ }
 456+ if ( isset( $params['token'] ) ) {
 457+ return 'private';
 458+ }
 459+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
 460+ // formatComment() calls wfMsg() among other things
 461+ return 'anon-public-user-private';
 462+ }
 463+ return 'public';
 464+ }
 465+
453466 public function getAllowedParams() {
454467 return array(
455468 'start' => array(
Index: trunk/phase3/includes/api/ApiQueryAllCategories.php
@@ -44,6 +44,10 @@
4545 $this->run();
4646 }
4747
 48+ public function getCacheMode( $params ) {
 49+ return 'public';
 50+ }
 51+
4852 public function executeGenerator( $resultPageSet ) {
4953 $this->run( $resultPageSet );
5054 }
@@ -179,4 +183,4 @@
180184 public function getVersion() {
181185 return __CLASS__ . ': $Id$';
182186 }
183 -}
\ No newline at end of file
 187+}
Index: trunk/phase3/includes/api/ApiWatch.php
@@ -41,7 +41,6 @@
4242
4343 public function execute() {
4444 global $wgUser;
45 - $this->getMain()->setCachePrivate();
4645 if ( !$wgUser->isLoggedIn() ) {
4746 $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
4847 }
Index: trunk/phase3/includes/api/ApiQueryLinks.php
@@ -65,6 +65,10 @@
6666 $this->run();
6767 }
6868
 69+ public function getCacheMode( $params ) {
 70+ return 'public';
 71+ }
 72+
6973 public function executeGenerator( $resultPageSet ) {
7074 $this->run( $resultPageSet );
7175 }
@@ -232,4 +236,4 @@
233237 public function getVersion() {
234238 return __CLASS__ . ': $Id$';
235239 }
236 -}
\ No newline at end of file
 240+}
Index: trunk/phase3/includes/api/ApiQueryRandom.php
@@ -119,6 +119,10 @@
120120 return $vals;
121121 }
122122
 123+ public function getCacheMode( $params ) {
 124+ return 'public';
 125+ }
 126+
123127 public function getAllowedParams() {
124128 return array(
125129 'namespace' => array(
@@ -160,4 +164,4 @@
161165 public function getVersion() {
162166 return __CLASS__ . ': $Id: ApiQueryRandom.php overlordq$';
163167 }
164 -}
\ No newline at end of file
 168+}
Index: trunk/phase3/includes/api/ApiQuerySiteinfo.php
@@ -427,6 +427,10 @@
428428 return $this->getResult()->addValue( 'query', $property, $data );
429429 }
430430
 431+ public function getCacheMode( $params ) {
 432+ return 'public';
 433+ }
 434+
431435 public function getAllowedParams() {
432436 return array(
433437 'prop' => array(
Index: trunk/phase3/includes/api/ApiLogout.php
@@ -42,7 +42,6 @@
4343
4444 public function execute() {
4545 global $wgUser;
46 - $this->getMain()->setCachePrivate();
4746 $oldName = $wgUser->getName();
4847 $wgUser->logout();
4948
Index: trunk/phase3/includes/api/ApiParse.php
@@ -38,6 +38,9 @@
3939 }
4040
4141 public function execute() {
 42+ // The data is hot but user-dependent, like page views, so we set vary cookies
 43+ $this->getMain()->setCacheMode( 'anon-public-user-private' );
 44+
4245 // Get parameters
4346 $params = $this->extractRequestParams();
4447 $text = $params['text'];
@@ -161,7 +164,6 @@
162165
163166 if ( $params['pst'] || $params['onlypst'] ) {
164167 $text = $wgParser->preSaveTransform( $text, $titleObj, $wgUser, $popts );
165 - $this->getMain()->setVaryCookie();
166168 }
167169 if ( $params['onlypst'] ) {
168170 // Build a result and bail out
@@ -187,7 +189,6 @@
188190
189191 if ( !is_null( $params['summary'] ) ) {
190192 $result_array['parsedsummary'] = array();
191 - $this->getMain()->setVaryCookie();
192193 $result->setContent( $result_array['parsedsummary'], $wgUser->getSkin()->formatComment( $params['summary'], $titleObj ) );
193194 }
194195
@@ -222,7 +223,6 @@
223224 if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) {
224225 $out = new OutputPage;
225226 $out->addParserOutputNoText( $p_result );
226 - $this->getMain()->setVaryCookie();
227227 $userSkin = $wgUser->getSkin();
228228 }
229229
@@ -468,4 +468,4 @@
469469 public function getVersion() {
470470 return __CLASS__ . ': $Id$';
471471 }
472 -}
\ No newline at end of file
 472+}
Index: trunk/phase3/includes/api/ApiQueryExtLinksUsage.php
@@ -41,6 +41,10 @@
4242 $this->run();
4343 }
4444
 45+ public function getCacheMode( $params ) {
 46+ return 'public';
 47+ }
 48+
4549 public function executeGenerator( $resultPageSet ) {
4650 $this->run( $resultPageSet );
4751 }
@@ -226,4 +230,4 @@
227231 public function getVersion() {
228232 return __CLASS__ . ': $Id$';
229233 }
230 -}
\ No newline at end of file
 234+}
Index: trunk/phase3/includes/api/ApiQueryAllpages.php
@@ -43,6 +43,10 @@
4444 $this->run();
4545 }
4646
 47+ public function getCacheMode( $params ) {
 48+ return 'public';
 49+ }
 50+
4751 public function executeGenerator( $resultPageSet ) {
4852 if ( $resultPageSet->isResolvingRedirects() ) {
4953 $this->dieUsage( 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params' );
Index: trunk/phase3/includes/api/ApiPurge.php
@@ -42,7 +42,6 @@
4343 */
4444 public function execute() {
4545 global $wgUser;
46 - $this->getMain()->setCachePrivate();
4746 $params = $this->extractRequestParams();
4847 if ( !$wgUser->isAllowed( 'purge' ) ) {
4948 $this->dieUsageMsg( array( 'cantpurge' ) );
Index: trunk/phase3/includes/api/ApiQueryBacklinks.php
@@ -92,6 +92,10 @@
9393 $this->run();
9494 }
9595
 96+ public function getCacheMode( $params ) {
 97+ return 'public';
 98+ }
 99+
96100 public function executeGenerator( $resultPageSet ) {
97101 $this->run( $resultPageSet );
98102 }
Index: trunk/phase3/includes/api/ApiQueryDeletedrevs.php
@@ -41,7 +41,6 @@
4242
4343 public function execute() {
4444 global $wgUser;
45 - $this->getMain()->setVaryCookie();
4645 // Before doing anything at all, let's check permissions
4746 if ( !$wgUser->isAllowed( 'deletedhistory' ) ) {
4847 $this->dieUsage( 'You don\'t have permission to view deleted revision information', 'permissiondenied' );
@@ -210,7 +209,6 @@
211210
212211 if ( $fld_parsedcomment ) {
213212 global $wgUser;
214 - $this->getMain()->setVaryCookie();
215213 $rev['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->ar_comment, $title );
216214 }
217215 if ( $fld_minor && $row->ar_minor_edit == 1 ) {
@@ -367,4 +365,4 @@
368366 public function getVersion() {
369367 return __CLASS__ . ': $Id$';
370368 }
371 -}
\ No newline at end of file
 369+}
Index: trunk/phase3/includes/api/ApiExpandTemplates.php
@@ -42,6 +42,9 @@
4343 }
4444
4545 public function execute() {
 46+ // Cache may vary on $wgUser because ParserOptions gets data from it
 47+ $this->getMain()->setCacheMode( 'anon-public-user-private' );
 48+
4649 // Get parameters
4750 $params = $this->extractRequestParams();
4851
Index: trunk/phase3/includes/api/ApiQueryBase.php
@@ -47,6 +47,17 @@
4848 }
4949
5050 /**
 51+ * Get the cache mode for the data generated by this module. Override this
 52+ * in the module subclass.
 53+ *
 54+ * Public caching will only be allowed if *all* the modules that supply
 55+ * data for a given request return a cache mode of public.
 56+ */
 57+ public function getCacheMode( $params ) {
 58+ return 'private';
 59+ }
 60+
 61+ /**
5162 * Blank the internal arrays with query parameters
5263 */
5364 protected function resetQueryParams() {
Index: trunk/phase3/includes/api/ApiQueryBlocks.php
@@ -125,8 +125,6 @@
126126 ) );
127127 }
128128
129 - // Make sure private data (deleted blocks) isn't cached
130 - $this->getMain()->setVaryCookie();
131129 if ( !$wgUser->isAllowed( 'hideuser' ) ) {
132130 $this->addWhereFld( 'ipb_deleted', 0 );
133131 }
@@ -308,4 +306,4 @@
309307 public function getVersion() {
310308 return __CLASS__ . ': $Id$';
311309 }
312 -}
\ No newline at end of file
 310+}
Index: trunk/phase3/includes/api/ApiQueryFilearchive.php
@@ -43,7 +43,6 @@
4444
4545 public function execute() {
4646 global $wgUser;
47 - $this->getMain()->setVaryCookie();
4847 // Before doing anything at all, let's check permissions
4948 if ( !$wgUser->isAllowed( 'deletedhistory' ) ) {
5049 $this->dieUsage( 'You don\'t have permission to view deleted file information', 'permissiondenied' );
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php
@@ -43,6 +43,10 @@
4444 $this->run();
4545 }
4646
 47+ public function getCacheMode( $params ) {
 48+ return 'public';
 49+ }
 50+
4751 public function executeGenerator( $resultPageSet ) {
4852 $this->run( $resultPageSet );
4953 }
Index: trunk/phase3/includes/api/ApiQueryCategoryInfo.php
@@ -94,6 +94,10 @@
9595 }
9696 }
9797
 98+ public function getCacheMode( $params ) {
 99+ return 'public';
 100+ }
 101+
98102 public function getAllowedParams() {
99103 return array(
100104 'continue' => null,
@@ -117,4 +121,4 @@
118122 public function getVersion() {
119123 return __CLASS__ . ': $Id$';
120124 }
121 -}
\ No newline at end of file
 125+}
Index: trunk/phase3/includes/api/ApiQueryAllimages.php
@@ -55,6 +55,10 @@
5656 $this->run();
5757 }
5858
 59+ public function getCacheMode( $params ) {
 60+ return 'public';
 61+ }
 62+
5963 public function executeGenerator( $resultPageSet ) {
6064 if ( $resultPageSet->isResolvingRedirects() ) {
6165 $this->dieUsage( 'Use "gaifilterredir=nonredirects" option instead of "redirects" when using allimages as a generator', 'params' );
Index: trunk/phase3/includes/api/ApiQueryAllmessages.php
@@ -45,12 +45,9 @@
4646 global $wgLang;
4747
4848 $oldLang = null;
49 - if ( !is_null( $params['lang'] ) && $params['lang'] != $wgLang->getCode() ) {
 49+ if ( !is_null( $params['lang'] ) ) {
5050 $oldLang = $wgLang; // Keep $wgLang for restore later
5151 $wgLang = Language::factory( $params['lang'] );
52 - } else if ( is_null( $params['lang'] ) ) {
53 - // Language not determined by URL but by user preferences, so don't cache
54 - $this->getMain()->setVaryCookie();
5552 }
5653
5754 $prop = array_flip( (array)$params['prop'] );
@@ -131,6 +128,19 @@
132129 }
133130 }
134131
 132+ public function getCacheMode( $params ) {
 133+ if ( is_null( $params['lang'] ) ) {
 134+ // Language not specified, will be fetched from preferences
 135+ return 'anon-public-user-private';
 136+ } elseif ( $params['enableparser'] ) {
 137+ // User-specific parser options will be used
 138+ return 'anon-public-user-private';
 139+ } else {
 140+ // OK to cache
 141+ return 'public';
 142+ }
 143+ }
 144+
135145 public function getAllowedParams() {
136146 return array(
137147 'messages' => array(
Index: trunk/phase3/includes/api/ApiQuerySearch.php
@@ -164,6 +164,10 @@
165165 }
166166 }
167167
 168+ public function getCacheMode( $params ) {
 169+ return 'public';
 170+ }
 171+
168172 public function getAllowedParams() {
169173 return array(
170174 'search' => null,
Index: trunk/phase3/includes/api/ApiQueryLogEvents.php
@@ -282,7 +282,6 @@
283283
284284 if ( $this->fld_parsedcomment ) {
285285 global $wgUser;
286 - $this->getMain()->setVaryCookie();
287286 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->log_comment, $title );
288287 }
289288 }
@@ -301,6 +300,15 @@
302301 return $vals;
303302 }
304303
 304+ public function getCacheMode( $params ) {
 305+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
 306+ // formatComment() calls wfMsg() among other things
 307+ return 'anon-public-user-private';
 308+ } else {
 309+ return 'public';
 310+ }
 311+ }
 312+
305313 public function getAllowedParams() {
306314 global $wgLogTypes, $wgLogActions;
307315 return array(
Index: trunk/phase3/includes/api/ApiQueryProtectedTitles.php
@@ -101,7 +101,6 @@
102102
103103 if ( isset( $prop['parsedcomment'] ) ) {
104104 global $wgUser;
105 - $this->getMain()->setVaryCookie();
106105 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->pt_reason, $title );
107106 }
108107
@@ -131,6 +130,15 @@
132131 }
133132 }
134133
 134+ public function getCacheMode( $params ) {
 135+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
 136+ // formatComment() calls wfMsg() among other things
 137+ return 'anon-public-user-private';
 138+ } else {
 139+ return 'public';
 140+ }
 141+ }
 142+
135143 public function getAllowedParams() {
136144 global $wgRestrictionLevels;
137145 return array(
@@ -210,4 +218,4 @@
211219 public function getVersion() {
212220 return __CLASS__ . ': $Id$';
213221 }
214 -}
\ No newline at end of file
 222+}
Index: trunk/phase3/includes/api/ApiQuery.php
@@ -232,9 +232,15 @@
233233 $this->instantiateModules( $modules, 'list', $this->mQueryListModules );
234234 $this->instantiateModules( $modules, 'meta', $this->mQueryMetaModules );
235235
 236+ $cacheMode = 'public';
 237+
236238 // If given, execute generator to substitute user supplied data with generated data.
237239 if ( isset( $this->params['generator'] ) ) {
238 - $this->executeGeneratorModule( $this->params['generator'], $modules );
 240+ $generator = $this->newGenerator( $this->params['generator'] );
 241+ $params = $generator->extractRequestParams();
 242+ $cacheMode = $this->mergeCacheMode( $cacheMode,
 243+ $generator->getCacheMode( $params ) );
 244+ $this->executeGeneratorModule( $generator, $modules );
239245 } else {
240246 // Append custom fields and populate page/revision information
241247 $this->addCustomFldsToPageSet( $modules, $this->mPageSet );
@@ -246,14 +252,38 @@
247253
248254 // Execute all requested modules.
249255 foreach ( $modules as $module ) {
 256+ $params = $module->extractRequestParams();
 257+ $cacheMode = $this->mergeCacheMode(
 258+ $cacheMode, $module->getCacheMode( $params ) );
250259 $module->profileIn();
251260 $module->execute();
252261 wfRunHooks( 'APIQueryAfterExecute', array( &$module ) );
253262 $module->profileOut();
254263 }
 264+
 265+ // Set the cache mode
 266+ $this->getMain()->setCacheMode( $cacheMode );
255267 }
256268
257269 /**
 270+ * Update a cache mode string, applying the cache mode of a new module to it.
 271+ * The cache mode may increase in the level of privacy, but public modules
 272+ * added to private data do not decrease the level of privacy.
 273+ */
 274+ protected function mergeCacheMode( $cacheMode, $modCacheMode ) {
 275+ if ( $modCacheMode === 'anon-public-user-private' ) {
 276+ if ( $cacheMode !== 'private' ) {
 277+ $cacheMode = 'anon-public-user-private';
 278+ }
 279+ } elseif ( $modCacheMode === 'public' ) {
 280+ // do nothing, if it's public already it will stay public
 281+ } else { // private
 282+ $cacheMode = 'private';
 283+ }
 284+ return $cacheMode;
 285+ }
 286+
 287+ /**
258288 * Query modules may optimize data requests through the $this->getPageSet() object
259289 * by adding extra fields from the page table.
260290 * This function will gather all the extra request fields from the modules.
@@ -458,12 +488,9 @@
459489 }
460490
461491 /**
462 - * For generator mode, execute generator, and use its output as new
463 - * ApiPageSet
464 - * @param $generatorName string Module name
465 - * @param $modules array of module objects
 492+ * Create a generator object of the given type and return it
466493 */
467 - protected function executeGeneratorModule( $generatorName, $modules ) {
 494+ public function newGenerator( $generatorName ) {
468495 // Find class that implements requested generator
469496 if ( isset( $this->mQueryListModules[$generatorName] ) ) {
470497 $className = $this->mQueryListModules[$generatorName];
@@ -472,18 +499,24 @@
473500 } else {
474501 ApiBase::dieDebug( __METHOD__, "Unknown generator=$generatorName" );
475502 }
476 -
477 - // Generator results
478 - $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
479 -
480 - // Create and execute the generator
481503 $generator = new $className ( $this, $generatorName );
482504 if ( !$generator instanceof ApiQueryGeneratorBase ) {
483505 $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
484506 }
485 -
486507 $generator->setGeneratorMode();
 508+ return $generator;
 509+ }
487510
 511+ /**
 512+ * For generator mode, execute generator, and use its output as new
 513+ * ApiPageSet
 514+ * @param $generatorName string Module name
 515+ * @param $modules array of module objects
 516+ */
 517+ protected function executeGeneratorModule( $generator, $modules ) {
 518+ // Generator results
 519+ $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
 520+
488521 // Add any additional fields modules may need
489522 $generator->requestExtraData( $this->mPageSet );
490523 $this->addCustomFldsToPageSet( $modules, $resultPageSet );
Index: trunk/phase3/includes/api/ApiQueryIWLinks.php
@@ -108,6 +108,10 @@
109109 }
110110 }
111111
 112+ public function getCacheMode( $params ) {
 113+ return 'public';
 114+ }
 115+
112116 public function getAllowedParams() {
113117 return array(
114118 'url' => null,
@@ -150,4 +154,4 @@
151155 public function getVersion() {
152156 return __CLASS__ . ': $Id$';
153157 }
154 -}
\ No newline at end of file
 158+}
Index: trunk/phase3/includes/api/ApiQueryLangLinks.php
@@ -95,6 +95,10 @@
9696 }
9797 }
9898
 99+ public function getCacheMode( $params ) {
 100+ return 'public';
 101+ }
 102+
99103 public function getAllowedParams() {
100104 return array(
101105 'limit' => array(
@@ -135,4 +139,4 @@
136140 public function getVersion() {
137141 return __CLASS__ . ': $Id$';
138142 }
139 -}
\ No newline at end of file
 143+}
Index: trunk/phase3/includes/api/ApiQueryUserInfo.php
@@ -40,7 +40,6 @@
4141 }
4242
4343 public function execute() {
44 - $this->getMain()->setCachePrivate();
4544 $params = $this->extractRequestParams();
4645 $result = $this->getResult();
4746 $r = array();
Index: trunk/phase3/includes/api/ApiMain.php
@@ -126,7 +126,8 @@
127127 private $mResult, $mAction, $mShowVersions, $mEnableWrite, $mRequest;
128128 private $mInternalMode, $mSquidMaxage, $mModule, $mVaryCookie;
129129
130 - private $mCacheControl = array( 'must-revalidate' => true );
 130+ private $mCacheMode = 'private';
 131+ private $mCacheControl = array();
131132
132133 /**
133134 * Constructs an instance of ApiMain that utilizes the module and format specified by $request.
@@ -216,19 +217,67 @@
217218 's-maxage' => $maxage
218219 ) );
219220 }
 221+
 222+ /**
 223+ * Set the type of caching headers which will be sent.
 224+ *
 225+ * @param $mode One of:
 226+ * - 'public': Cache this object in public caches, if the maxage or smaxage
 227+ * parameter is set, or if setCacheMaxAge() was called. If a maximum age is
 228+ * not provided by any of these means, the object will be private.
 229+ * - 'private': Cache this object only in private client-side caches.
 230+ * - 'anon-public-user-private': Make this object cacheable for logged-out
 231+ * users, but private for logged-in users. IMPORTANT: If this is set, it must be
 232+ * set consistently for a given URL, it cannot be set differently depending on
 233+ * things like the contents of the database, or whether the user is logged in.
 234+ *
 235+ * If the wiki does not allow anonymous users to read it, the mode set here
 236+ * will be ignored, and private caching headers will always be sent. In other words,
 237+ * the "public" mode is equivalent to saying that the data sent is as public as a page
 238+ * view.
 239+ *
 240+ * For user-dependent data, the private mode should generally be used. The
 241+ * anon-public-user-private mode should only be used where there is a particularly
 242+ * good performance reason for caching the anonymous response, but where the
 243+ * response to logged-in users may differ, or may contain private data.
 244+ *
 245+ * If this function is never called, then the default will be the private mode.
 246+ */
 247+ public function setCacheMode( $mode ) {
 248+ if ( !in_array( $mode, array( 'private', 'public', 'anon-public-user-private' ) ) ) {
 249+ wfDebug( __METHOD__.": unrecognised cache mode \"$mode\"\n" );
 250+ // Ignore for forwards-compatibility
 251+ return;
 252+ }
 253+
 254+ if ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) {
 255+ // Private wiki, only private headers
 256+ if ( $mode !== 'private' ) {
 257+ wfDebug( __METHOD__.": ignoring request for $mode cache mode, private wiki\n" );
 258+ return;
 259+ }
 260+ }
 261+
 262+ wfDebug( __METHOD__.": setting cache mode $mode\n" );
 263+ $this->mCacheMode = $mode;
 264+ }
220265
221266 /**
222 - * Make sure Cache-Control: private is set. Use this when the output of a request
223 - * is for the current recipient only and should not be cached in any shared cache.
 267+ * @deprecated Private caching is now the default, so there is usually no
 268+ * need to call this function. If there is a need, you can use
 269+ * $this->setCacheMode('private')
224270 */
225271 public function setCachePrivate() {
226 - $this->setCacheControl( array( 'private' => true ) );
 272+ $this->setCacheMode( 'private' );
227273 }
228274
229275 /**
230276 * Set directives (key/value pairs) for the Cache-Control header.
231277 * Boolean values will be formatted as such, by including or omitting
232278 * without an equals sign.
 279+ *
 280+ * Cache control values set here will only be used if the cache mode is not
 281+ * private, see setCacheMode().
233282 */
234283 public function setCacheControl( $directives ) {
235284 $this->mCacheControl = $directives + $this->mCacheControl;
@@ -241,27 +290,12 @@
242291 * WARNING: This function must be called CONSISTENTLY for a given URL. This means that a
243292 * given URL must either always or never call this function; if it sometimes does and
244293 * sometimes doesn't, stuff will break.
 294+ *
 295+ * @deprecated Use setCacheMode( 'anon-public-user-private' )
245296 */
246297 public function setVaryCookie() {
247 - $this->mVaryCookie = true;
 298+ $this->setCacheMode( 'anon-public-user-private' );
248299 }
249 -
250 - /**
251 - * Actually output the Vary: Cookie header and its friends, if flagged with setVaryCookie().
252 - * Outputs the appropriate X-Vary-Options header and Cache-Control: private if needed.
253 - */
254 - private function outputVaryCookieHeader() {
255 - global $wgUseXVO, $wgOut;
256 - if ( $this->mVaryCookie ) {
257 - header( 'Vary: Cookie' );
258 - if ( $wgUseXVO ) {
259 - header( $wgOut->getXVO() );
260 - if ( $wgOut->haveCacheVaryCookies() ) {
261 - $this->setCacheControl( array( 'private' => true ) );
262 - }
263 - }
264 - }
265 - }
266300
267301 /**
268302 * Create an instance of an output formatter by its name
@@ -313,8 +347,7 @@
314348 $errCode = $this->substituteResultWithError( $e );
315349
316350 // Error results should not be cached
317 - $this->setCacheMaxAge( 0 );
318 - $this->setCachePrivate();
 351+ $this->setCacheMode( 'private' );
319352
320353 $headerStr = 'MediaWiki-API-Error: ' . $errCode;
321354 if ( $e->getCode() === 0 ) {
@@ -330,12 +363,49 @@
331364 $this->mPrinter->safeProfileOut();
332365 $this->printResult( true );
333366 }
334 -
335 - // If this wiki is private, don't cache anything ever
336 - if ( ! in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) {
337 - $this->setCachePrivate();
 367+
 368+ // Send cache headers after any code which might generate an error, to
 369+ // avoid sending public cache headers for errors.
 370+ $this->sendCacheHeaders();
 371+
 372+ if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) {
 373+ echo wfReportTime();
338374 }
339375
 376+ ob_end_flush();
 377+ }
 378+
 379+ protected function sendCacheHeaders() {
 380+ if ( $this->mCacheMode == 'private' ) {
 381+ header( 'Cache-Control: private' );
 382+ return;
 383+ }
 384+
 385+ if ( $this->mCacheMode == 'anon-public-user-private' ) {
 386+ global $wgUseXVO, $wgOut;
 387+ header( 'Vary: Accept-Encoding, Cookie' );
 388+ if ( $wgUseXVO ) {
 389+ header( $wgOut->getXVO() );
 390+ if ( $wgOut->haveCacheVaryCookies() ) {
 391+ // Logged in, mark this request private
 392+ header( 'Cache-Control: private' );
 393+ return;
 394+ }
 395+ // Logged out, send normal public headers below
 396+ } elseif ( session_id() != '' ) {
 397+ // Logged in or otherwise has session (e.g. anonymous users who have edited)
 398+ // Mark request private
 399+ header( 'Cache-Control: private' );
 400+ return;
 401+ } // else no XVO and anonymous, send public headers below
 402+ } else /* if public */ {
 403+ // Give a debugging message if the user object is unstubbed on a public request
 404+ global $wgUser;
 405+ if ( !( $wgUser instanceof StubUser ) ) {
 406+ wfDebug( __METHOD__." \$wgUser is unstubbed on a public request!\n" );
 407+ }
 408+ }
 409+
340410 // If nobody called setCacheMaxAge(), use the (s)maxage parameters
341411 if ( !isset( $this->mCacheControl['s-maxage'] ) ) {
342412 $this->mCacheControl['s-maxage'] = $this->getParameter( 'smaxage' );
@@ -344,12 +414,21 @@
345415 $this->mCacheControl['max-age'] = $this->getParameter( 'maxage' );
346416 }
347417
348 - // Set the cache expiration at the last moment, as any errors may change the expiration.
349 - // if $this->mSquidMaxage == 0, the expiry time is set to the first second of unix epoch
350 - $exp = min( $this->mCacheControl['s-maxage'], $this->mCacheControl['max-age'] );
351 - $expires = ( $exp == 0 ? 1 : time() + $exp );
352 - header( 'Expires: ' . wfTimestamp( TS_RFC2822, $expires ) );
 418+ if ( !$this->mCacheControl['s-maxage'] && !$this->mCacheControl['max-age'] ) {
 419+ // Public cache not requested
 420+ // Sending a Vary header in this case is harmless, and protects us
 421+ // against conditional calls of setCacheMaxAge().
 422+ header( 'Cache-Control: private' );
 423+ return;
 424+ }
353425
 426+ $this->mCacheControl['public'] = true;
 427+
 428+ // Send an Expires header
 429+ $maxAge = min( $this->mCacheControl['s-maxage'], $this->mCacheControl['max-age'] );
 430+ $expiryUnixTime = ( $maxAge == 0 ? 1 : time() + $maxAge );
 431+ header( 'Expires: ' . wfTimestamp( TS_RFC2822, $expiryUnixTime ) );
 432+
354433 // Construct the Cache-Control header
355434 $ccHeader = '';
356435 $separator = '';
@@ -366,13 +445,6 @@
367446 }
368447
369448 header( "Cache-Control: $ccHeader" );
370 - $this->outputVaryCookieHeader();
371 -
372 - if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) {
373 - echo wfReportTime();
374 - }
375 -
376 - ob_end_flush();
377449 }
378450
379451 /**
Index: trunk/phase3/includes/api/ApiQueryImageInfo.php
@@ -274,6 +274,10 @@
275275 return $retval;
276276 }
277277
 278+ public function getCacheMode( $params ) {
 279+ return 'public';
 280+ }
 281+
278282 private function getContinueStr( $img ) {
279283 return $img->getOriginalTitle()->getText() .
280284 '|' . $img->getTimestamp();
Index: trunk/phase3/includes/api/ApiOpenSearch.php
@@ -56,7 +56,7 @@
5757 // Open search results may be stored for a very long
5858 // time
5959 $this->getMain()->setCacheMaxAge( $wgSearchSuggestCacheExpiry );
60 - $this->getMain()->setCacheControl( array( 'must-revalidate' => false ) );
 60+ $this->getMain()->setCacheMode( 'public' );
6161
6262 $srchres = PrefixSearch::titleSearch( $search, $limit,
6363 $namespaces );
Index: trunk/phase3/includes/api/ApiQueryIWBacklinks.php
@@ -147,6 +147,10 @@
148148 }
149149 }
150150
 151+ public function getCacheMode( $params ) {
 152+ return 'public';
 153+ }
 154+
151155 public function getAllowedParams() {
152156 return array(
153157 'prefix' => null,
Index: trunk/phase3/includes/api/ApiQueryWatchlist.php
@@ -74,7 +74,6 @@
7575 $this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] );
7676
7777 if ( $this->fld_patrol ) {
78 - $this->getMain()->setVaryCookie();
7978 if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
8079 $this->dieUsage( 'patrol property is not available', 'patrol' );
8180 }
@@ -141,9 +140,8 @@
142141 $this->dieUsageMsg( array( 'show' ) );
143142 }
144143
145 - // Check permissions. FIXME: should this check $user instead of $wgUser?
 144+ // Check permissions.
146145 if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) {
147 - $this->getMain()->setVaryCookie();
148146 if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) {
149147 $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
150148 }
@@ -272,7 +270,6 @@
273271
274272 if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) {
275273 global $wgUser;
276 - $this->getMain()->setVaryCookie();
277274 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title );
278275 }
279276
Index: trunk/phase3/includes/api/ApiPatrol.php
@@ -41,7 +41,6 @@
4242 * Patrols the article or provides the reason the patrol failed.
4343 */
4444 public function execute() {
45 - $this->getMain()->setCachePrivate();
4645 $params = $this->extractRequestParams();
4746
4847 if ( !isset( $params['rcid'] ) ) {
@@ -107,4 +106,4 @@
108107 public function getVersion() {
109108 return __CLASS__ . ': $Id$';
110109 }
111 -}
\ No newline at end of file
 110+}
Index: trunk/phase3/includes/api/ApiQueryRevisions.php
@@ -394,7 +394,6 @@
395395
396396 if ( $this->fld_parsedcomment ) {
397397 global $wgUser;
398 - $this->getMain()->setVaryCookie();
399398 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $comment, $title );
400399 }
401400 }
@@ -411,9 +410,6 @@
412411 }
413412
414413 if ( !is_null( $this->token ) ) {
415 - // Don't cache tokens
416 - $this->getMain()->setCachePrivate();
417 -
418414 $tokenFunctions = $this->getTokenFunctions();
419415 foreach ( $this->token as $t ) {
420416 $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision );
@@ -487,6 +483,17 @@
488484 return $vals;
489485 }
490486
 487+ public function getCacheMode( $params ) {
 488+ if ( isset( $params['token'] ) ) {
 489+ return 'private';
 490+ }
 491+ if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
 492+ // formatComment() calls wfMsg() among other things
 493+ return 'anon-public-user-private';
 494+ }
 495+ return 'public';
 496+ }
 497+
491498 public function getAllowedParams() {
492499 return array(
493500 'prop' => array(
Index: trunk/phase3/includes/api/ApiQueryExternalLinks.php
@@ -83,6 +83,10 @@
8484 }
8585 }
8686
 87+ public function getCacheMode( $params ) {
 88+ return 'public';
 89+ }
 90+
8791 public function getAllowedParams() {
8892 return array(
8993 'limit' => array(
@@ -117,4 +121,4 @@
118122 public function getVersion() {
119123 return __CLASS__ . ': $Id$';
120124 }
121 -}
\ No newline at end of file
 125+}
Index: trunk/phase3/includes/api/ApiBase.php
@@ -1105,8 +1105,6 @@
11061106 $this->dieUsage( 'Incorrect watchlist token provided -- please set a correct token in Special:Preferences', 'bad_wltoken' );
11071107 }
11081108 } else {
1109 - // User not determined by URL, so don't cache
1110 - $this->getMain()->setVaryCookie();
11111109 if ( !$wgUser->isLoggedIn() ) {
11121110 $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
11131111 }
Index: trunk/phase3/includes/api/ApiQueryCategories.php
@@ -43,6 +43,10 @@
4444 $this->run();
4545 }
4646
 47+ public function getCacheMode( $params ) {
 48+ return 'public';
 49+ }
 50+
4751 public function executeGenerator( $resultPageSet ) {
4852 $this->run( $resultPageSet );
4953 }
Index: trunk/phase3/includes/api/ApiQueryAllUsers.php
@@ -184,6 +184,10 @@
185185 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'u' );
186186 }
187187
 188+ public function getCacheMode( $params ) {
 189+ return 'public';
 190+ }
 191+
188192 public function getAllowedParams() {
189193 return array(
190194 'from' => null,
@@ -241,4 +245,4 @@
242246 public function getVersion() {
243247 return __CLASS__ . ': $Id$';
244248 }
245 -}
\ No newline at end of file
 249+}
Index: trunk/phase3/includes/api/ApiQueryInfo.php
@@ -253,7 +253,6 @@
254254 }
255255
256256 if ( $this->fld_watched ) {
257 - $this->getMain()->setVaryCookie();
258257 $this->getWatchedInfo();
259258 }
260259
@@ -304,9 +303,6 @@
305304 }
306305
307306 if ( !is_null( $this->params['token'] ) ) {
308 - // Don't cache tokens
309 - $this->getMain()->setCachePrivate();
310 -
311307 $tokenFunctions = $this->getTokenFunctions();
312308 $pageInfo['starttimestamp'] = wfTimestamp( TS_ISO_8601, time() );
313309 foreach ( $this->params['token'] as $t ) {
@@ -607,6 +603,28 @@
608604 }
609605 }
610606
 607+ public function getCacheMode( $params ) {
 608+ $publicProps = array(
 609+ 'protection',
 610+ 'talkid',
 611+ 'subjectid',
 612+ 'url',
 613+ 'preload',
 614+ 'displaytitle',
 615+ );
 616+ if ( !is_null( $params['prop'] ) ) {
 617+ foreach ( $params['prop'] as $prop ) {
 618+ if ( !in_array( $prop, $publicProps ) ) {
 619+ return 'private';
 620+ }
 621+ }
 622+ }
 623+ if ( !is_null( $params['token'] ) ) {
 624+ return 'private';
 625+ }
 626+ return 'public';
 627+ }
 628+
611629 public function getAllowedParams() {
612630 return array(
613631 'prop' => array(
@@ -615,12 +633,14 @@
616634 ApiBase::PARAM_TYPE => array(
617635 'protection',
618636 'talkid',
619 - 'watched',
 637+ 'watched', # private
620638 'subjectid',
621639 'url',
622 - 'readable',
 640+ 'readable', # private
623641 'preload',
624642 'displaytitle',
 643+ // If you add more properties here, please consider whether they
 644+ // need to be added to getCacheMode()
625645 ) ),
626646 'token' => array(
627647 ApiBase::PARAM_DFLT => null,
Index: trunk/phase3/includes/api/ApiQueryDuplicateFiles.php
@@ -43,6 +43,10 @@
4444 $this->run();
4545 }
4646
 47+ public function getCacheMode( $params ) {
 48+ return 'public';
 49+ }
 50+
4751 public function executeGenerator( $resultPageSet ) {
4852 $this->run( $resultPageSet );
4953 }
Index: trunk/phase3/includes/api/ApiQueryTags.php
@@ -129,6 +129,10 @@
130130 return true;
131131 }
132132
 133+ public function getCacheMode( $params ) {
 134+ return 'public';
 135+ }
 136+
133137 public function getAllowedParams() {
134138 return array(
135139 'continue' => array(
Index: trunk/phase3/includes/api/ApiQueryUserContributions.php
@@ -163,8 +163,6 @@
164164 );
165165 }
166166
167 - // Make sure private data (deleted revisions) isn't cached
168 - $this->getMain()->setVaryCookie();
169167 if ( !$wgUser->isAllowed( 'hideuser' ) ) {
170168 $this->addWhere( $this->getDB()->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' );
171169 }
@@ -216,8 +214,6 @@
217215 $this->fld_patrolled )
218216 {
219217 global $wgUser;
220 - // Don't cache private data
221 - $this->getMain()->setVaryCookie();
222218 if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) {
223219 $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
224220 }
@@ -320,7 +316,6 @@
321317
322318 if ( $this->fld_parsedcomment ) {
323319 global $wgUser;
324 - $this->getMain()->setVaryCookie();
325320 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rev_comment, $title );
326321 }
327322 }
@@ -352,6 +347,12 @@
353348 wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
354349 }
355350
 351+ public function getCacheMode( $params ) {
 352+ // This module provides access to deleted revisions and patrol flags if
 353+ // the requester is logged in
 354+ return 'anon-public-user-private';
 355+ }
 356+
356357 public function getAllowedParams() {
357358 return array(
358359 'limit' => array(
Index: trunk/phase3/includes/api/ApiQueryUsers.php
@@ -160,9 +160,6 @@
161161 }
162162
163163 if ( !is_null( $params['token'] ) ) {
164 - // Don't cache tokens
165 - $this->getMain()->setCachePrivate();
166 -
167164 $tokenFunctions = $this->getTokenFunctions();
168165 foreach ( $params['token'] as $t ) {
169166 $val = call_user_func( $tokenFunctions[$t], $user );
@@ -235,6 +232,14 @@
236233 return array_merge( $groups, Autopromote::getAutopromoteGroups( $user ) );
237234 }
238235
 236+ public function getCacheMode( $params ) {
 237+ if ( isset( $params['token'] ) ) {
 238+ return 'private';
 239+ } else {
 240+ return 'public';
 241+ }
 242+ }
 243+
239244 public function getAllowedParams() {
240245 return array(
241246 'prop' => array(
Index: trunk/phase3/includes/api/ApiQueryImages.php
@@ -121,6 +121,10 @@
122122 }
123123 }
124124
 125+ public function getCacheMode( $params ) {
 126+ return 'public';
 127+ }
 128+
125129 public function getAllowedParams() {
126130 return array(
127131 'limit' => array(
@@ -163,4 +167,4 @@
164168 public function getVersion() {
165169 return __CLASS__ . ': $Id$';
166170 }
167 -}
\ No newline at end of file
 171+}

Follow-up revisions

RevisionCommit summaryAuthorDate
r69782Followup to r69776: cache result of extractRequestParams() because it gets ca...catrope10:15, 23 July 2010
r69784Followup to r69776: remove calls to setCachePrivate() and setVaryCookie() fro...catrope11:17, 23 July 2010
r69931Fix for r69776: remove unused variable ApiMain::$mVaryCookietstarling07:35, 26 July 2010
r69932* MFT r69776, and followups r69784, r69928, r69931, and superseded base revis...tstarling08:03, 26 July 2010
r70061Brought the API cache header handling into sync with the REL1_16 branch, by r...tstarling02:01, 28 July 2010

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r69339API: Make output containing private or user-specific data uncacheable for log...catrope19:00, 14 July 2010

Comments

#Comment by MarkAHershberger (talk | contribs)   02:55, 27 July 2010

(Commenting here since this seems to be the most appropriate place.)

Why create a new sendCacheHeaders() instead of refactoring/reusing wgOut's sendCacheControl()? It looks like wgOut's code has a little more complete cache control built in (though, I'm not sure how much is relevant to the API code).

Related: Is there a reason $wgRequest->response() and $wgRequest->response()->header() aren't used in the API code? I can see ways that it would make testing easier if they were used.

#Comment by Catrope (talk | contribs)   20:49, 14 December 2010

No reason the API can't use WebResponse, and I do see why that'd make testing easier. Feel free to convert header() calls in the API to WebResponse style.

Status & tagging log