MediaWiki REL1_40
SpecialRunJobs.php
Go to the documentation of this file.
1<?php
25
32
34 private $jobRunner;
35
37 private $readOnlyMode;
38
43 public function __construct(
44 JobRunner $jobRunner,
45 ReadOnlyMode $readOnlyMode
46 ) {
47 parent::__construct( 'RunJobs' );
48 $this->jobRunner = $jobRunner;
49 $this->readOnlyMode = $readOnlyMode;
50 }
51
52 public function doesWrites() {
53 return true;
54 }
55
56 public function execute( $par ) {
57 $this->getOutput()->disable();
58
59 if ( $this->readOnlyMode->isReadOnly() ) {
60 wfHttpError( 423, 'Locked', 'Wiki is in read-only mode.' );
61 return;
62 }
63
64 // Validate request method
65 if ( !$this->getRequest()->wasPosted() ) {
66 wfHttpError( 400, 'Bad Request', 'Request must be POSTed.' );
67 return;
68 }
69
70 // Validate request parameters
71 $optional = [ 'maxjobs' => 0, 'maxtime' => 30, 'type' => false,
72 'async' => true, 'stats' => false ];
73 $required = array_fill_keys( [ 'title', 'tasks', 'signature', 'sigexpiry' ], true );
74 $params = array_intersect_key( $this->getRequest()->getValues(), $required + $optional );
75 $missing = array_diff_key( $required, $params );
76 if ( count( $missing ) ) {
77 wfHttpError( 400, 'Bad Request',
78 'Missing parameters: ' . implode( ', ', array_keys( $missing ) )
79 );
80 return;
81 }
82
83 // Validate request signature
84 $squery = $params;
85 unset( $squery['signature'] );
86 $correctSignature = self::getQuerySignature( $squery,
87 $this->getConfig()->get( MainConfigNames::SecretKey ) );
88 $providedSignature = $params['signature'];
89 $verified = is_string( $providedSignature )
90 && hash_equals( $correctSignature, $providedSignature );
91 if ( !$verified || $params['sigexpiry'] < time() ) {
92 wfHttpError( 400, 'Bad Request', 'Invalid or stale signature provided.' );
93 return;
94 }
95
96 // Apply any default parameter values
97 $params += $optional;
98
99 if ( $params['async'] ) {
100 // HTTP 202 Accepted
101 HttpStatus::header( 202 );
102 // Clients are meant to disconnect without waiting for the full response.
103 // Let the page output happen before the jobs start, so that clients know it's
104 // safe to disconnect. MediaWiki::preOutputCommit() calls ignore_user_abort()
105 // or similar to make sure we stay alive to run the deferred update.
106 DeferredUpdates::addUpdate(
108 function () use ( $params ) {
109 $this->doRun( $params );
110 },
111 __METHOD__
112 ),
113 DeferredUpdates::POSTSEND
114 );
115 } else {
116 $stats = $this->doRun( $params );
117
118 if ( $params['stats'] ) {
119 $this->getRequest()->response()->header( 'Content-Type: application/json' );
120 print FormatJson::encode( $stats );
121 } else {
122 print "Done\n";
123 }
124 }
125 }
126
127 protected function doRun( array $params ) {
128 return $this->jobRunner->run( [
129 'type' => $params['type'],
130 'maxJobs' => $params['maxjobs'] ?: 1,
131 'maxTime' => $params['maxtime'] ?: 30
132 ] );
133 }
134
140 public static function getQuerySignature( array $query, $secretKey ) {
141 ksort( $query ); // stable order
142 return hash_hmac( 'sha1', wfArrayToCgi( $query ), $secretKey );
143 }
144}
wfHttpError( $code, $label, $desc)
Provide a simple HTTP error.
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
Job queue runner utility methods.
Definition JobRunner.php:40
A class containing constants representing the names of configuration variables.
A service class for fetching the wiki's current read-only mode.
getOutput()
Get the OutputPage being used for this instance.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
Special page designed for running background tasks (internal use only)
__construct(JobRunner $jobRunner, ReadOnlyMode $readOnlyMode)
doRun(array $params)
execute( $par)
Default execute method Checks user permissions.
doesWrites()
Indicates whether this special page may perform database writes.
static getQuerySignature(array $query, $secretKey)
Deferrable update that must run outside of any explicit LBFactory transaction round.
Shortcut to construct a special page which is unlisted by default.