MediaWiki master
EntryPoint.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Rest;
4
20
25
26 private RequestInterface $request;
27 private ?Router $router = null;
28 private ?CorsUtils $cors = null;
29
41 public static function createRouter(
42 MediaWikiServices $services,
43 IContextSource $context,
44 RequestInterface $request,
45 ResponseFactory $responseFactory,
46 CorsUtils $cors
47 ): Router {
48 $conf = $services->getMainConfig();
49
50 $authority = $context->getAuthority();
51 $authorizer = new CompoundAuthorizer();
52 $authorizer
53 ->addAuthorizer( new MWBasicAuthorizer( $authority ) )
54 ->addAuthorizer( $cors );
55
56 $objectFactory = $services->getObjectFactory();
57 $restValidator = new Validator( $objectFactory,
58 $request,
59 $authority
60 );
61
62 $stats = $services->getStatsFactory();
63
64 return ( new Router(
65 self::getRouteFiles( $conf ),
66 ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
68 $services->getLocalServerObjectCache(),
69 $responseFactory,
70 $authorizer,
71 $authority,
72 $objectFactory,
73 $restValidator,
74 new MWErrorReporter(),
75 $services->getHookContainer(),
76 $context->getRequest()->getSession()
77 ) )
78 ->setCors( $cors )
79 ->setStats( $stats );
80 }
81
86 public static function getMainRequest(): RequestInterface {
87 static $mainRequest = null;
88
89 if ( $mainRequest === null ) {
90 $conf = MediaWikiServices::getInstance()->getMainConfig();
91 $mainRequest = new RequestFromGlobals( [
92 'cookiePrefix' => $conf->get( MainConfigNames::CookiePrefix )
93 ] );
94 }
95
96 return $mainRequest;
97 }
98
99 protected function doSetup() {
100 parent::doSetup();
101
102 $context = RequestContext::getMain();
103
104 $responseFactory = new ResponseFactory( $this->getTextFormatters() );
105 $responseFactory->setShowExceptionDetails(
106 MWExceptionRenderer::shouldShowExceptionDetails()
107 );
108
109 $this->cors = new CorsUtils(
110 new ServiceOptions(
111 CorsUtils::CONSTRUCTOR_OPTIONS,
112 $this->getServiceContainer()->getMainConfig()
113 ),
114 $responseFactory,
115 $context->getUser()
116 );
117
118 if ( !$this->router ) {
119 $this->router = $this->createRouter(
120 $this->getServiceContainer(),
121 $context,
122 $this->request,
123 $responseFactory,
124 $this->cors
125 );
126 }
127 }
128
134 private function getTextFormatters() {
135 $services = $this->getServiceContainer();
136
137 $code = $services->getContentLanguageCode()->toString();
138 $langs = array_unique( [ $code, 'en' ] );
139 $textFormatters = [];
140 $factory = $services->getMessageFormatterFactory();
141
142 foreach ( $langs as $lang ) {
143 $textFormatters[] = $factory->getTextFormatter( $lang );
144 }
145
146 return $textFormatters;
147 }
148
154 private static function getRouteFiles( $conf ) {
155 global $IP;
156 $extensionsDir = $conf->get( MainConfigNames::ExtensionDirectory );
157 // Always include the "official" routes. Include additional routes if specified.
158 $routeFiles = array_merge(
159 [
160 'includes/Rest/coreRoutes.json',
161 ],
162 $conf->get( MainConfigNames::RestAPIAdditionalRouteFiles )
163 );
164 foreach ( $routeFiles as &$file ) {
165 if (
166 str_starts_with( $file, '/' )
167 ) {
168 // Allow absolute paths on non-Windows
169 } elseif (
170 str_starts_with( $file, 'extensions/' )
171 ) {
172 // Support hacks like Wikibase.ci.php
173 $file = substr_replace( $file, $extensionsDir,
174 0, strlen( 'extensions' ) );
175 } else {
176 $file = "$IP/$file";
177 }
178 }
179
180 return $routeFiles;
181 }
182
183 public function __construct(
184 RequestInterface $request,
185 RequestContext $context,
186 EntryPointEnvironment $environment,
187 MediaWikiServices $mediaWikiServices
188 ) {
189 parent::__construct( $context, $environment, $mediaWikiServices );
190
191 $this->request = $request;
192 }
193
200 public function setRouter( Router $router ): void {
201 $this->router = $router;
202 }
203
204 public function execute() {
205 $this->startOutputBuffer();
206
207 // IDEA: Move the call to cors->modifyResponse() into Module,
208 // so it's in the same class as cors->createPreflightResponse().
209 $response = $this->cors->modifyResponse(
210 $this->request,
211 $this->router->execute( $this->request )
212 );
213
214 $webResponse = $this->getResponse();
215
216 $webResponse->header(
217 'HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' .
218 $response->getReasonPhrase()
219 );
220
221 foreach ( $response->getRawHeaderLines() as $line ) {
222 $webResponse->header( $line );
223 }
224
225 foreach ( $response->getCookies() as $cookie ) {
226 $webResponse->setCookie(
227 $cookie['name'],
228 $cookie['value'],
229 $cookie['expiry'],
230 $cookie['options']
231 );
232 }
233
234 // Clear all errors that might have been displayed if display_errors=On
235 $this->discardOutputBuffer();
236
237 $stream = $response->getBody();
238 $stream->rewind();
239
240 $this->prepareForOutput();
241
242 if ( $stream instanceof CopyableStreamInterface ) {
243 $stream->copyToStream( fopen( 'php://output', 'w' ) );
244 } else {
245 while ( true ) {
246 $buffer = $stream->read( 65536 );
247 if ( $buffer === '' ) {
248 break;
249 }
250 $this->print( $buffer );
251 }
252 }
253 }
254
255}
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Definition Setup.php:103
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.
Utility class wrapping PHP runtime state.
A class containing constants representing the names of configuration variables.
const CookiePrefix
Name constant for the CookiePrefix setting, for use with Config::get()
Base class for entry point handlers.
Service locator for MediaWiki core services.
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.
Load JSON files, and uses a Processor to extract information.
A factory for MWBasicRequestAuthorizer which passes through a UserIdentity.
doSetup()
Perform any setup needed before execute() is called.
setRouter(Router $router)
Sets the router to use.
__construct(RequestInterface $request, RequestContext $context, EntryPointEnvironment $environment, MediaWikiServices $mediaWikiServices)
execute()
Subclasses implement the entry point's functionality by overriding this method.
static createRouter(MediaWikiServices $services, IContextSource $context, RequestInterface $request, ResponseFactory $responseFactory, 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.
setShowExceptionDetails(bool $showExceptionDetails)
Control whether web responses may include a exception messager and backtrace.
The REST router is responsible for gathering module configuration, matching an input path against the...
Definition Router.php:30
const CONSTRUCTOR_OPTIONS
Definition Router.php:82
Wrapper for ParamValidator.
Definition Validator.php:37
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.