return;
}
- $useXVO = $config->get( 'UseXVO' );
+ $useKeyHeader = $config->get( 'UseKeyHeader' );
if ( $this->mCacheMode == 'anon-public-user-private' ) {
$out->addVaryHeader( 'Cookie' );
$response->header( $out->getVaryHeader() );
- if ( $useXVO ) {
- $response->header( $out->getXVO() );
+ if ( $useKeyHeader ) {
+ $response->header( $out->getKeyHeader() );
if ( $out->haveCacheVaryCookies() ) {
// Logged in, mark this request private
$response->header( "Cache-Control: $privateCache" );
$response->header( "Cache-Control: $privateCache" );
return;
- } // else no XVO and anonymous, send public headers below
+ } // else no Key and anonymous, send public headers below
}
// Send public headers
$response->header( $out->getVaryHeader() );
- if ( $useXVO ) {
- $response->header( $out->getXVO() );
+ if ( $useKeyHeader ) {
+ $response->header( $out->getKeyHeader() );
}
// If nobody called setCacheMaxAge(), use the (s)maxage parameters
}
if ( $config->get( 'ShowHostnames' ) ) {
// servedby is especially useful when debugging errors
- $result->addValue( null, 'servedby', wfHostName(), ApiResult::NO_SIZE_CHECK );
+ $result->addValue( null, 'servedby', wfHostname(), ApiResult::NO_SIZE_CHECK );
}
if ( $warnings !== null ) {
$result->addValue( null, 'warnings', $warnings, ApiResult::NO_SIZE_CHECK );
*/
protected function checkMaxLag( $module, $params ) {
if ( $module->shouldCheckMaxlag() && isset( $params['maxlag'] ) ) {
- // Check for maxlag
$maxLag = $params['maxlag'];
list( $host, $lag ) = wfGetLB()->getMaxLag();
if ( $lag > $maxLag ) {
) {
$this->dieUsageMsg( 'readrequired' );
}
+
if ( $module->isWriteMode() ) {
if ( !$this->mEnableWrite ) {
$this->dieUsageMsg( 'writedisabled' );
- }
- if ( !$user->isAllowed( 'writeapi' ) ) {
+ } elseif ( !$user->isAllowed( 'writeapi' ) ) {
$this->dieUsageMsg( 'writerequired' );
+ } elseif ( $this->getRequest()->getHeader( 'Promise-Non-Write-API-Action' ) ) {
+ $this->dieUsage(
+ "Promise-Non-Write-API-Action HTTP header cannot be sent to write API modules",
+ 'promised-nonwrite-api'
+ );
}
- if ( wfReadOnly() ) {
- $this->dieReadOnly();
- }
+
+ $this->checkReadOnly( $module );
}
// Allow extensions to stop execution for arbitrary reasons.
}
}
+ /**
+ * Check if the DB is read-only for this user
+ * @param ApiBase $module An Api module
+ */
+ protected function checkReadOnly( $module ) {
+ if ( wfReadOnly() ) {
+ $this->dieReadOnly();
+ }
+
+ if ( $module->isWriteMode()
+ && in_array( 'bot', $this->getUser()->getGroups() )
+ && wfGetLB()->getServerCount() > 1
+ ) {
+ // Figure out how many servers have passed the lag threshold
+ $numLagged = 0;
+ $lagLimit = $this->getConfig()->get( 'APIMaxLagThreshold' );
+ foreach ( wfGetLB()->getLagTimes() as $lag ) {
+ if ( $lag > $lagLimit ) {
+ ++$numLagged;
+ }
+ }
+ // If a majority of slaves are too lagged then disallow writes
+ $slaveCount = wfGetLB()->getServerCount() - 1;
+ if ( $numLagged >= ceil( $slaveCount / 2 ) ) {
+ $parsed = $this->parseMsg( array( 'readonlytext' ) );
+ $this->dieUsage(
+ $parsed['info'],
+ $parsed['code'],
+ /* http error */
+ 0,
+ array( 'readonlyreason' => "Waiting for $numLagged lagged database(s)" )
+ );
+ }
+ }
+ }
+
/**
* Check asserts of the user's rights
* @param array $params
$tocnumber = &$options['tocnumber'];
$header = $this->msg( 'api-help-datatypes-header' )->parse();
- $help['datatypes'] .= Html::rawelement( 'h' . min( 6, $level ),
+ $help['datatypes'] .= Html::rawElement( 'h' . min( 6, $level ),
array( 'id' => 'main/datatypes', 'class' => 'apihelp-header' ),
Html::element( 'span', array( 'id' => Sanitizer::escapeId( 'main/datatypes' ) ) ) .
$header
}
$header = $this->msg( 'api-credits-header' )->parse();
- $help['credits'] .= Html::rawelement( 'h' . min( 6, $level ),
+ $help['credits'] .= Html::rawElement( 'h' . min( 6, $level ),
array( 'id' => 'main/credits', 'class' => 'apihelp-header' ),
Html::element( 'span', array( 'id' => Sanitizer::escapeId( 'main/credits' ) ) ) .
$header
*/
public function makeHelpMsg() {
wfDeprecated( __METHOD__, '1.25' );
- global $wgMemc;
- $this->setHelp();
- // Get help text from cache if present
- $key = wfMemcKey( 'apihelp', $this->getModuleName(),
- str_replace( ' ', '_', SpecialVersion::getVersion( 'nodb' ) ) );
+ $this->setHelp();
$cacheHelpTimeout = $this->getConfig()->get( 'APICacheHelpTimeout' );
- if ( $cacheHelpTimeout > 0 ) {
- $cached = $wgMemc->get( $key );
- if ( $cached ) {
- return $cached;
- }
- }
- $retval = $this->reallyMakeHelpMsg();
- if ( $cacheHelpTimeout > 0 ) {
- $wgMemc->set( $key, $retval, $cacheHelpTimeout );
- }
- return $retval;
+ return ObjectCache::getMainWANInstance()->getWithSetCallback(
+ wfMemcKey(
+ 'apihelp',
+ $this->getModuleName(),
+ str_replace( ' ', '_', SpecialVersion::getVersion( 'nodb' ) )
+ ),
+ $cacheHelpTimeout > 0 ? $cacheHelpTimeout : WANObjectCache::TTL_UNCACHEABLE,
+ array( $this, 'reallyMakeHelpMsg' )
+ );
}
/**