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