MediaWiki
REL1_23
|
00001 <?php 00030 class AjaxResponse { 00035 private $mCacheDuration; 00036 00041 private $mContentType; 00042 00047 private $mDisabled; 00048 00053 private $mLastModified; 00054 00059 private $mResponseCode; 00060 00065 private $mVary; 00066 00071 private $mText; 00072 00076 function __construct( $text = null ) { 00077 $this->mCacheDuration = null; 00078 $this->mVary = null; 00079 00080 $this->mDisabled = false; 00081 $this->mText = ''; 00082 $this->mResponseCode = '200 OK'; 00083 $this->mLastModified = false; 00084 $this->mContentType = 'application/x-wiki'; 00085 00086 if ( $text ) { 00087 $this->addText( $text ); 00088 } 00089 } 00090 00095 function setCacheDuration( $duration ) { 00096 $this->mCacheDuration = $duration; 00097 } 00098 00103 function setVary( $vary ) { 00104 $this->mVary = $vary; 00105 } 00106 00111 function setResponseCode( $code ) { 00112 $this->mResponseCode = $code; 00113 } 00114 00119 function setContentType( $type ) { 00120 $this->mContentType = $type; 00121 } 00122 00126 function disable() { 00127 $this->mDisabled = true; 00128 } 00129 00134 function addText( $text ) { 00135 if ( ! $this->mDisabled && $text ) { 00136 $this->mText .= $text; 00137 } 00138 } 00139 00143 function printText() { 00144 if ( ! $this->mDisabled ) { 00145 print $this->mText; 00146 } 00147 } 00148 00152 function sendHeaders() { 00153 global $wgUseSquid, $wgUseESI; 00154 00155 if ( $this->mResponseCode ) { 00156 $n = preg_replace( '/^ *(\d+)/', '\1', $this->mResponseCode ); 00157 header( "Status: " . $this->mResponseCode, true, (int)$n ); 00158 } 00159 00160 header ( "Content-Type: " . $this->mContentType ); 00161 00162 if ( $this->mLastModified ) { 00163 header ( "Last-Modified: " . $this->mLastModified ); 00164 } else { 00165 header ( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" ); 00166 } 00167 00168 if ( $this->mCacheDuration ) { 00169 # If squid caches are configured, tell them to cache the response, 00170 # and tell the client to always check with the squid. Otherwise, 00171 # tell the client to use a cached copy, without a way to purge it. 00172 00173 if ( $wgUseSquid ) { 00174 # Expect explicit purge of the proxy cache, but require end user agents 00175 # to revalidate against the proxy on each visit. 00176 # Surrogate-Control controls our Squid, Cache-Control downstream caches 00177 00178 if ( $wgUseESI ) { 00179 header( 'Surrogate-Control: max-age=' . $this->mCacheDuration . ', content="ESI/1.0"' ); 00180 header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' ); 00181 } else { 00182 header( 'Cache-Control: s-maxage=' . $this->mCacheDuration . ', must-revalidate, max-age=0' ); 00183 } 00184 00185 } else { 00186 # Let the client do the caching. Cache is not purged. 00187 header ( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT" ); 00188 header ( "Cache-Control: s-maxage={$this->mCacheDuration}," . 00189 "public,max-age={$this->mCacheDuration}" ); 00190 } 00191 00192 } else { 00193 # always expired, always modified 00194 header ( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" ); // Date in the past 00195 header ( "Cache-Control: no-cache, must-revalidate" ); // HTTP/1.1 00196 header ( "Pragma: no-cache" ); // HTTP/1.0 00197 } 00198 00199 if ( $this->mVary ) { 00200 header ( "Vary: " . $this->mVary ); 00201 } 00202 } 00203 00212 function checkLastModified( $timestamp ) { 00213 global $wgCachePages, $wgCacheEpoch, $wgUser; 00214 $fname = 'AjaxResponse::checkLastModified'; 00215 00216 if ( !$timestamp || $timestamp == '19700101000000' ) { 00217 wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n", 'log' ); 00218 return false; 00219 } 00220 00221 if ( !$wgCachePages ) { 00222 wfDebug( "$fname: CACHE DISABLED\n", 'log' ); 00223 return false; 00224 } 00225 00226 $timestamp = wfTimestamp( TS_MW, $timestamp ); 00227 $lastmod = wfTimestamp( TS_RFC2822, max( $timestamp, $wgUser->getTouched(), $wgCacheEpoch ) ); 00228 00229 if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) { 00230 # IE sends sizes after the date like this: 00231 # Wed, 20 Aug 2003 06:51:19 GMT; length=5202 00232 # this breaks strtotime(). 00233 $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] ); 00234 $modsinceTime = strtotime( $modsince ); 00235 $ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 ); 00236 wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", 'log' ); 00237 wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", 'log' ); 00238 00239 if ( ( $ismodsince >= $timestamp ) 00240 && $wgUser->validateCache( $ismodsince ) && 00241 $ismodsince >= $wgCacheEpoch 00242 ) { 00243 ini_set( 'zlib.output_compression', 0 ); 00244 $this->setResponseCode( "304 Not Modified" ); 00245 $this->disable(); 00246 $this->mLastModified = $lastmod; 00247 00248 wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; " . 00249 "page: $timestamp ; site $wgCacheEpoch\n", 'log' ); 00250 00251 return true; 00252 } else { 00253 wfDebug( "$fname: READY client: $ismodsince ; user: {$wgUser->getTouched()} ; " . 00254 "page: $timestamp ; site $wgCacheEpoch\n", 'log' ); 00255 $this->mLastModified = $lastmod; 00256 } 00257 } else { 00258 wfDebug( "$fname: client did not send If-Modified-Since header\n", 'log' ); 00259 $this->mLastModified = $lastmod; 00260 } 00261 return false; 00262 } 00263 00269 function loadFromMemcached( $mckey, $touched ) { 00270 global $wgMemc; 00271 00272 if ( !$touched ) { 00273 return false; 00274 } 00275 00276 $mcvalue = $wgMemc->get( $mckey ); 00277 if ( $mcvalue ) { 00278 # Check to see if the value has been invalidated 00279 if ( $touched <= $mcvalue['timestamp'] ) { 00280 wfDebug( "Got $mckey from cache\n" ); 00281 $this->mText = $mcvalue['value']; 00282 00283 return true; 00284 } else { 00285 wfDebug( "$mckey has expired\n" ); 00286 } 00287 } 00288 00289 return false; 00290 } 00291 00297 function storeInMemcached( $mckey, $expiry = 86400 ) { 00298 global $wgMemc; 00299 00300 $wgMemc->set( $mckey, 00301 array( 00302 'timestamp' => wfTimestampNow(), 00303 'value' => $this->mText 00304 ), $expiry 00305 ); 00306 00307 return true; 00308 } 00309 }