MediaWiki  master
EntryPoint.php
Go to the documentation of this file.
1 <?php
2 
3 namespace MediaWiki\Rest;
4 
5 use Config;
8 use MediaWiki;
17 use RequestContext;
18 use Title;
19 use WebResponse;
21 
22 class EntryPoint {
24  private $request;
26  private $webResponse;
28  private $router;
30  private $context;
32  private $cors;
34  private static $mainRequest;
35 
45  private static function createRouter(
46  MediaWikiServices $services,
47  IContextSource $context,
48  RequestInterface $request,
49  ResponseFactory $responseFactory,
50  CorsUtils $cors
51  ): Router {
52  $conf = $services->getMainConfig();
53 
54  $authority = $context->getAuthority();
55  $authorizer = new CompoundAuthorizer();
56  $authorizer
57  ->addAuthorizer( new MWBasicAuthorizer( $authority ) )
58  ->addAuthorizer( $cors );
59 
60  $objectFactory = $services->getObjectFactory();
61  $restValidator = new Validator( $objectFactory,
62  $request,
63  $authority
64  );
65 
66  $metrics = $services->getStatsdDataFactory();
67 
68  return ( new Router(
69  self::getRouteFiles( $conf ),
70  ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
71  new ServiceOptions( Router::CONSTRUCTOR_OPTIONS, $conf ),
72  $services->getLocalServerObjectCache(),
73  $responseFactory,
74  $authorizer,
75  $authority,
76  $objectFactory,
77  $restValidator,
78  new MWErrorReporter(),
79  $services->getHookContainer(),
80  $context->getRequest()->getSession()
81  ) )
82  ->setCors( $cors )
83  ->setMetrics( $metrics );
84  }
85 
89  public static function getMainRequest(): RequestInterface {
90  if ( self::$mainRequest === null ) {
91  $conf = MediaWikiServices::getInstance()->getMainConfig();
92  self::$mainRequest = new RequestFromGlobals( [
93  'cookiePrefix' => $conf->get( MainConfigNames::CookiePrefix )
94  ] );
95  }
96  return self::$mainRequest;
97  }
98 
99  public static function main() {
100  // URL safety checks
101  global $wgRequest;
102 
103  $context = RequestContext::getMain();
104 
105  // Set $wgTitle and the title in RequestContext, as in api.php
106  global $wgTitle;
107  $wgTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/rest.php' );
108  $context->setTitle( $wgTitle );
109 
110  $services = MediaWikiServices::getInstance();
111  $conf = $services->getMainConfig();
112 
113  $responseFactory = new ResponseFactory( self::getTextFormatters( $services ) );
114  $responseFactory->setShowExceptionDetails( MWExceptionRenderer::shouldShowExceptionDetails() );
115 
116  $cors = new CorsUtils(
117  new ServiceOptions(
118  CorsUtils::CONSTRUCTOR_OPTIONS, $conf
119  ),
120  $responseFactory,
121  $context->getUser()
122  );
123 
124  $request = self::getMainRequest();
125 
126  $router = self::createRouter( $services, $context, $request, $responseFactory, $cors );
127 
128  $entryPoint = new self(
129  $context,
130  $request,
131  $wgRequest->response(),
132  $router,
133  $cors
134  );
135  $entryPoint->execute();
136  }
137 
144  private static function getTextFormatters( MediaWikiServices $services ) {
145  $code = $services->getContentLanguage()->getCode();
146  $langs = array_unique( [ $code, 'en' ] );
147  $textFormatters = [];
148  $factory = $services->getMessageFormatterFactory();
149 
150  foreach ( $langs as $lang ) {
151  $textFormatters[] = $factory->getTextFormatter( $lang );
152  }
153  return $textFormatters;
154  }
155 
160  private static function getRouteFiles( $conf ) {
161  global $IP;
162  $extensionsDir = $conf->get( MainConfigNames::ExtensionDirectory );
163  // Always include the "official" routes. Include additional routes if specified.
164  $routeFiles = array_merge(
165  [ 'includes/Rest/coreRoutes.json' ],
167  );
168  foreach ( $routeFiles as &$file ) {
169  if ( str_starts_with( $file, '/' ) ) {
170  // Allow absolute paths on non-Windows
171  } elseif ( str_starts_with( $file, 'extensions/' ) ) {
172  // Support hacks like Wikibase.ci.php
173  $file = substr_replace( $file, $extensionsDir, 0, strlen( 'extensions' ) );
174  } else {
175  $file = "$IP/$file";
176  }
177  }
178  return $routeFiles;
179  }
180 
181  public function __construct( RequestContext $context, RequestInterface $request,
182  WebResponse $webResponse, Router $router, CorsUtils $cors
183  ) {
184  $this->context = $context;
185  $this->request = $request;
186  $this->webResponse = $webResponse;
187  $this->router = $router;
188  $this->cors = $cors;
189  }
190 
191  public function execute() {
192  ob_start();
193  $response = $this->cors->modifyResponse(
194  $this->request,
195  $this->router->execute( $this->request )
196  );
197 
198  $this->webResponse->header(
199  'HTTP/' . $response->getProtocolVersion() . ' ' .
200  $response->getStatusCode() . ' ' .
201  $response->getReasonPhrase() );
202 
203  foreach ( $response->getRawHeaderLines() as $line ) {
204  $this->webResponse->header( $line );
205  }
206 
207  foreach ( $response->getCookies() as $cookie ) {
208  $this->webResponse->setCookie(
209  $cookie['name'],
210  $cookie['value'],
211  $cookie['expiry'],
212  $cookie['options'] );
213  }
214 
215  // Clear all errors that might have been displayed if display_errors=On
216  ob_end_clean();
217 
218  $stream = $response->getBody();
219  $stream->rewind();
220 
221  MediaWiki::preOutputCommit( $this->context );
222 
223  if ( $stream instanceof CopyableStreamInterface ) {
224  $stream->copyToStream( fopen( 'php://output', 'w' ) );
225  } else {
226  while ( true ) {
227  $buffer = $stream->read( 65536 );
228  if ( $buffer === '' ) {
229  break;
230  }
231  echo $buffer;
232  }
233  }
234 
235  $mw = new MediaWiki;
236  $mw->doPostOutputShutdown();
237  }
238 }
const NS_SPECIAL
Definition: Defines.php:53
if(!defined( 'MEDIAWIKI')) if(ini_get( 'mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Definition: Setup.php:91
global $wgRequest
Definition: Setup.php:373
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgTitle
Definition: Setup.php:493
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition: WebStart.php:82
The Registry loads JSON files, and uses a Processor to extract information from them.
Class to expose exceptions to the client (API bots, users, admins using CLI scripts)
A class for passing options to services.
A class containing constants representing the names of configuration variables.
const ExtensionDirectory
Name constant for the ExtensionDirectory setting, for use with Config::get()
const CookiePrefix
Name constant for the CookiePrefix setting, for use with Config::get()
const RestAPIAdditionalRouteFiles
Name constant for the RestAPIAdditionalRouteFiles setting, for use with Config::get()
Service locator for MediaWiki core services.
getMainConfig()
Returns the Config object that provides configuration for MediaWiki core.
getLocalServerObjectCache()
Returns the main server-local cache, yielding EmptyBagOStuff if there is none.
getObjectFactory()
ObjectFactory is intended for instantiating "handlers" from declarative definitions,...
static getInstance()
Returns the global default instance of the top level service locator.
A factory for MWBasicRequestAuthorizer which passes through a UserIdentity.
__construct(RequestContext $context, RequestInterface $request, WebResponse $webResponse, Router $router, CorsUtils $cors)
Definition: EntryPoint.php:181
Error reporter based on MWExceptionHandler.
This is a request class that gets data directly from the superglobals and other global PHP state,...
Generates standardized response objects.
The REST router is responsible for gathering handler configuration, matching an input path and HTTP m...
Definition: Router.php:27
Wrapper for ParamValidator.
Definition: Validator.php:32
The MediaWiki class is the helper class for the index.php entry point.
Definition: MediaWiki.php:39
doPostOutputShutdown()
This function does work that can be done after the user gets the HTTP response so they don't block on...
Definition: MediaWiki.php:808
static preOutputCommit(IContextSource $context, $postCommitWork=null)
This function commits all DB and session changes as needed before the client can receive a response (...
Definition: MediaWiki.php:652
Group all the pieces relevant to the context of a request into one instance.
static getMain()
Get the RequestContext object associated with the main request.
Represents a title within MediaWiki.
Definition: Title.php:52
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:641
Allow programs to request this object from WebRequest::response() and handle all outputting (or lack ...
Definition: WebResponse.php:31
Interface for configuration instances.
Definition: Config.php:30
Interface for objects which can provide a MediaWiki context on request.
An interface for a stream with a copyToStream() function.
A request interface similar to PSR-7's ServerRequestInterface.
$line
Definition: mcc.php:119
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
if(!isset( $args[0])) $lang