Merge "Make DBAccessBase use DBConnRef, rename $wiki, and hide getLoadBalancer()"
[lhc/web/wiklou.git] / includes / Rest / EntryPoint.php
1 <?php
2
3 namespace MediaWiki\Rest;
4
5 use ExtensionRegistry;
6 use MediaWiki;
7 use MediaWiki\MediaWikiServices;
8 use MediaWiki\Rest\BasicAccess\MWBasicAuthorizer;
9 use MediaWiki\Rest\Validator\Validator;
10 use RequestContext;
11 use Title;
12 use WebResponse;
13
14 class EntryPoint {
15 /** @var RequestInterface */
16 private $request;
17 /** @var WebResponse */
18 private $webResponse;
19 /** @var Router */
20 private $router;
21 /** @var RequestContext */
22 private $context;
23
24 public static function main() {
25 // URL safety checks
26 global $wgRequest;
27 if ( !$wgRequest->checkUrlExtension() ) {
28 return;
29 }
30
31 $context = RequestContext::getMain();
32
33 // Set $wgTitle and the title in RequestContext, as in api.php
34 global $wgTitle;
35 $wgTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/rest.php' );
36 $context->setTitle( $wgTitle );
37
38 $services = MediaWikiServices::getInstance();
39 $conf = $services->getMainConfig();
40 $objectFactory = $services->getObjectFactory();
41
42 if ( !$conf->get( 'EnableRestAPI' ) ) {
43 wfHttpError( 403, 'Access Denied',
44 'Set $wgEnableRestAPI to true to enable the experimental REST API' );
45 return;
46 }
47
48 $request = new RequestFromGlobals( [
49 'cookiePrefix' => $conf->get( 'CookiePrefix' )
50 ] );
51
52 // @phan-suppress-next-line PhanAccessMethodInternal
53 $authorizer = new MWBasicAuthorizer( $context->getUser(),
54 $services->getPermissionManager() );
55
56 // @phan-suppress-next-line PhanAccessMethodInternal
57 $restValidator = new Validator( $objectFactory, $request, RequestContext::getMain()->getUser() );
58
59 global $IP;
60 $router = new Router(
61 [ "$IP/includes/Rest/coreRoutes.json" ],
62 ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
63 $conf->get( 'RestPath' ),
64 $services->getLocalServerObjectCache(),
65 new ResponseFactory,
66 $authorizer,
67 $objectFactory,
68 $restValidator
69 );
70
71 $entryPoint = new self(
72 $context,
73 $request,
74 $wgRequest->response(),
75 $router );
76 $entryPoint->execute();
77 }
78
79 public function __construct( RequestContext $context, RequestInterface $request,
80 WebResponse $webResponse, Router $router
81 ) {
82 $this->context = $context;
83 $this->request = $request;
84 $this->webResponse = $webResponse;
85 $this->router = $router;
86 }
87
88 public function execute() {
89 ob_start();
90 $response = $this->router->execute( $this->request );
91
92 $this->webResponse->header(
93 'HTTP/' . $response->getProtocolVersion() . ' ' .
94 $response->getStatusCode() . ' ' .
95 $response->getReasonPhrase() );
96
97 foreach ( $response->getRawHeaderLines() as $line ) {
98 $this->webResponse->header( $line );
99 }
100
101 foreach ( $response->getCookies() as $cookie ) {
102 $this->webResponse->setCookie(
103 $cookie['name'],
104 $cookie['value'],
105 $cookie['expiry'],
106 $cookie['options'] );
107 }
108
109 // Clear all errors that might have been displayed if display_errors=On
110 ob_end_clean();
111
112 $stream = $response->getBody();
113 $stream->rewind();
114
115 MediaWiki::preOutputCommit( $this->context );
116
117 if ( $stream instanceof CopyableStreamInterface ) {
118 $stream->copyToStream( fopen( 'php://output', 'w' ) );
119 } else {
120 while ( true ) {
121 $buffer = $stream->read( 65536 );
122 if ( $buffer === '' ) {
123 break;
124 }
125 echo $buffer;
126 }
127 }
128
129 $mw = new MediaWiki;
130 $mw->doPostOutputShutdown( 'fast' );
131 }
132 }