| Index: trunk/phase3/includes/resourceloader/ResourceLoader.php |
| — | — | @@ -353,7 +353,7 @@ |
| 354 | 354 | * @param $context ResourceLoaderContext: Context in which a response should be formed |
| 355 | 355 | */ |
| 356 | 356 | public function respond( ResourceLoaderContext $context ) { |
| 357 | | - global $wgResourceLoaderMaxage, $wgCacheEpoch; |
| | 357 | + global $wgCacheEpoch; |
| 358 | 358 | |
| 359 | 359 | // Buffer output to catch warnings. Normally we'd use ob_clean() on the |
| 360 | 360 | // top-level output buffer to clear warnings, but that breaks when ob_gzhandler |
| — | — | @@ -378,19 +378,6 @@ |
| 379 | 379 | } |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | | - // If a version wasn't specified we need a shorter expiry time for updates |
| 383 | | - // to propagate to clients quickly |
| 384 | | - if ( is_null( $context->getVersion() ) ) { |
| 385 | | - $maxage = $wgResourceLoaderMaxage['unversioned']['client']; |
| 386 | | - $smaxage = $wgResourceLoaderMaxage['unversioned']['server']; |
| 387 | | - } |
| 388 | | - // If a version was specified we can use a longer expiry time since changing |
| 389 | | - // version numbers causes cache misses |
| 390 | | - else { |
| 391 | | - $maxage = $wgResourceLoaderMaxage['versioned']['client']; |
| 392 | | - $smaxage = $wgResourceLoaderMaxage['versioned']['server']; |
| 393 | | - } |
| 394 | | - |
| 395 | 382 | // Preload information needed to the mtime calculation below |
| 396 | 383 | try { |
| 397 | 384 | $this->preloadModuleInfo( array_keys( $modules ), $context ); |
| — | — | @@ -421,6 +408,53 @@ |
| 422 | 409 | |
| 423 | 410 | wfProfileOut( __METHOD__.'-getModifiedTime' ); |
| 424 | 411 | |
| | 412 | + // Send content type and cache related headers |
| | 413 | + $this->sendResponseHeaders( $context, $mtime, $private ); |
| | 414 | + |
| | 415 | + // If there's an If-Modified-Since header, respond with a 304 appropriately |
| | 416 | + if ( $this->tryRespondLastModified( $context, $mtime ) ) { |
| | 417 | + return; // output handled (buffers cleared) |
| | 418 | + } |
| | 419 | + |
| | 420 | + // Generate a response |
| | 421 | + $response = $this->makeModuleResponse( $context, $modules, $missing ); |
| | 422 | + |
| | 423 | + // Prepend comments indicating exceptions |
| | 424 | + $response = $exceptions . $response; |
| | 425 | + |
| | 426 | + // Capture any PHP warnings from the output buffer and append them to the |
| | 427 | + // response in a comment if we're in debug mode. |
| | 428 | + if ( $context->getDebug() && strlen( $warnings = ob_get_contents() ) ) { |
| | 429 | + $response = "/*\n$warnings\n*/\n" . $response; |
| | 430 | + } |
| | 431 | + |
| | 432 | + // Remove the output buffer and output the response |
| | 433 | + ob_end_clean(); |
| | 434 | + echo $response; |
| | 435 | + |
| | 436 | + wfProfileOut( __METHOD__ ); |
| | 437 | + } |
| | 438 | + |
| | 439 | + /** |
| | 440 | + * Send content type and last modified headers to the client. |
| | 441 | + * @param $context ResourceLoaderContext |
| | 442 | + * @param $mtime string TS_MW timestamp to use for last-modified |
| | 443 | + * @param $private bool True iff response contains any private modules |
| | 444 | + * @return void |
| | 445 | + */ |
| | 446 | + protected function sendResponseHeaders( ResourceLoaderContext $context, $mtime, $private ) { |
| | 447 | + global $wgResourceLoaderMaxage; |
| | 448 | + // If a version wasn't specified we need a shorter expiry time for updates |
| | 449 | + // to propagate to clients quickly |
| | 450 | + if ( is_null( $context->getVersion() ) ) { |
| | 451 | + $maxage = $wgResourceLoaderMaxage['unversioned']['client']; |
| | 452 | + $smaxage = $wgResourceLoaderMaxage['unversioned']['server']; |
| | 453 | + // If a version was specified we can use a longer expiry time since changing |
| | 454 | + // version numbers causes cache misses |
| | 455 | + } else { |
| | 456 | + $maxage = $wgResourceLoaderMaxage['versioned']['client']; |
| | 457 | + $smaxage = $wgResourceLoaderMaxage['versioned']['server']; |
| | 458 | + } |
| 425 | 459 | if ( $context->getOnly() === 'styles' ) { |
| 426 | 460 | header( 'Content-Type: text/css; charset=utf-8' ); |
| 427 | 461 | } else { |
| — | — | @@ -441,7 +475,16 @@ |
| 442 | 476 | } |
| 443 | 477 | header( 'Expires: ' . wfTimestamp( TS_RFC2822, $exp + time() ) ); |
| 444 | 478 | } |
| | 479 | + } |
| 445 | 480 | |
| | 481 | + /** |
| | 482 | + * If there's an If-Modified-Since header, respond with a 304 appropriately |
| | 483 | + * and clear out the output buffer. If the client cache is too old then do nothing. |
| | 484 | + * @param $context ResourceLoaderContext |
| | 485 | + * @param $mtime string The TS_MW timestamp to check the header against |
| | 486 | + * @return bool True iff 304 header sent and output handled |
| | 487 | + */ |
| | 488 | + protected function tryRespondLastModified( ResourceLoaderContext $context, $mtime ) { |
| 446 | 489 | // If there's an If-Modified-Since header, respond with a 304 appropriately |
| 447 | 490 | // Some clients send "timestamp;length=123". Strip the part after the first ';' |
| 448 | 491 | // so we get a valid timestamp. |
| — | — | @@ -470,27 +513,10 @@ |
| 471 | 514 | header( 'HTTP/1.0 304 Not Modified' ); |
| 472 | 515 | header( 'Status: 304 Not Modified' ); |
| 473 | 516 | wfProfileOut( __METHOD__ ); |
| 474 | | - return; |
| | 517 | + return true; |
| 475 | 518 | } |
| 476 | 519 | } |
| 477 | | - |
| 478 | | - // Generate a response |
| 479 | | - $response = $this->makeModuleResponse( $context, $modules, $missing ); |
| 480 | | - |
| 481 | | - // Prepend comments indicating exceptions |
| 482 | | - $response = $exceptions . $response; |
| 483 | | - |
| 484 | | - // Capture any PHP warnings from the output buffer and append them to the |
| 485 | | - // response in a comment if we're in debug mode. |
| 486 | | - if ( $context->getDebug() && strlen( $warnings = ob_get_contents() ) ) { |
| 487 | | - $response = "/*\n$warnings\n*/\n" . $response; |
| 488 | | - } |
| 489 | | - |
| 490 | | - // Remove the output buffer and output the response |
| 491 | | - ob_end_clean(); |
| 492 | | - echo $response; |
| 493 | | - |
| 494 | | - wfProfileOut( __METHOD__ ); |
| | 520 | + return false; |
| 495 | 521 | } |
| 496 | 522 | |
| 497 | 523 | /** |
| — | — | @@ -793,6 +819,8 @@ |
| 794 | 820 | * |
| 795 | 821 | * @param $id String: source ID |
| 796 | 822 | * @param $properties Array: source properties (see addSource()) |
| | 823 | + * |
| | 824 | + * @return string |
| 797 | 825 | */ |
| 798 | 826 | public static function makeLoaderSourcesScript( $id, $properties = null ) { |
| 799 | 827 | if ( is_array( $id ) ) { |