MediaWiki master
EntryPoint.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Rest;
4
6use MediaWiki;
21
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 $stats = $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 ->setStats( $stats );
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:98
global $wgRequest
Definition Setup.php:415
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli') $wgTitle
Definition Setup.php:536
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Load JSON files, and uses a Processor to extract information.
Class to expose exceptions to the client (API bots, users, admins using CLI scripts)
A class for passing options to services.
Group all the pieces relevant to the context of a request into one instance.
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.
Allow programs to request this object from WebRequest::response() and handle all outputting (or lack ...
A factory for MWBasicRequestAuthorizer which passes through a UserIdentity.
__construct(RequestContext $context, RequestInterface $request, WebResponse $webResponse, Router $router, CorsUtils $cors)
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:28
Wrapper for ParamValidator.
Definition Validator.php:32
Represents a title within MediaWiki.
Definition Title.php:78
Interface for configuration instances.
Definition Config.php:32
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.
A helper class for throttling authentication attempts.