getOutput()->disable(); if ( wfReadOnly() ) { // HTTP 423 Locked HttpStatus::header( 423 ); print 'Wiki is in read-only mode'; return; } elseif ( !$this->getRequest()->wasPosted() ) { HttpStatus::header( 400 ); print 'Request must be POSTed'; return; } $optional = array( 'maxjobs' => 0, 'maxtime' => 30, 'type' => false, 'async' => true ); $required = array_flip( array( 'title', 'tasks', 'signature', 'sigexpiry' ) ); $params = array_intersect_key( $this->getRequest()->getValues(), $required + $optional ); $missing = array_diff_key( $required, $params ); if ( count( $missing ) ) { HttpStatus::header( 400 ); print 'Missing parameters: ' . implode( ', ', array_keys( $missing ) ); return; } $squery = $params; unset( $squery['signature'] ); $correctSignature = self::getQuerySignature( $squery, $this->getConfig()->get( 'SecretKey' ) ); $providedSignature = $params['signature']; $verified = is_string( $providedSignature ) && hash_equals( $correctSignature, $providedSignature ); if ( !$verified || $params['sigexpiry'] < time() ) { HttpStatus::header( 400 ); print 'Invalid or stale signature provided'; return; } // Apply any default parameter values $params += $optional; if ( $params['async'] ) { // Client will usually disconnect before checking the response, // but it needs to know when it is safe to disconnect. Until this // reaches ignore_user_abort(), it is not safe as the jobs won't run. ignore_user_abort( true ); // jobs may take a bit of time // HTTP 202 Accepted HttpStatus::header( 202 ); ob_flush(); flush(); // Once the client receives this response, it can disconnect } // Do all of the specified tasks... if ( in_array( 'jobs', explode( '|', $params['tasks'] ) ) ) { $runner = new JobRunner( LoggerFactory::getInstance( 'runJobs' ) ); $response = $runner->run( array( 'type' => $params['type'], 'maxJobs' => $params['maxjobs'] ? $params['maxjobs'] : 1, 'maxTime' => $params['maxtime'] ? $params['maxjobs'] : 30 ) ); if ( !$params['async'] ) { print FormatJson::encode( $response, true ); } } } /** * @param array $query * @param string $secretKey * @return string */ public static function getQuerySignature( array $query, $secretKey ) { ksort( $query ); // stable order return hash_hmac( 'sha1', wfArrayToCgi( $query ), $secretKey ); } }