From: Tim Starling Date: Fri, 16 Aug 2019 04:38:48 +0000 (+1000) Subject: REST: call MediaWiki::preOutputCommit and doPostOutputShutdown X-Git-Tag: 1.34.0-rc.0~569^2 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dmembres/cotisations/gestion/rappel_supprimer.php?a=commitdiff_plain;h=86693df2470314e220c0f4d027e7d84174929209;p=lhc%2Fweb%2Fwiklou.git REST: call MediaWiki::preOutputCommit and doPostOutputShutdown As in api.php. Among other things, this enables profiling. Move EntryPoint test out of unit/ so that it passes. Use ob_start()/ob_end_clean() instead of assuming an output buffer is open, so that EntryPoint::execute() can be run from CLI mode. Change-Id: I38162a9eac6fd5acfed2035b87cac4a97ffd50d6 --- diff --git a/includes/Rest/EntryPoint.php b/includes/Rest/EntryPoint.php index ae01ae46ac..a4959d1504 100644 --- a/includes/Rest/EntryPoint.php +++ b/includes/Rest/EntryPoint.php @@ -3,6 +3,7 @@ namespace MediaWiki\Rest; use ExtensionRegistry; +use MediaWiki; use MediaWiki\MediaWikiServices; use MediaWiki\Rest\BasicAccess\MWBasicAuthorizer; use RequestContext; @@ -16,6 +17,8 @@ class EntryPoint { private $webResponse; /** @var Router */ private $router; + /** @var RequestContext */ + private $context; public static function main() { // URL safety checks @@ -24,10 +27,12 @@ class EntryPoint { return; } + $context = RequestContext::getMain(); + // Set $wgTitle and the title in RequestContext, as in api.php global $wgTitle; $wgTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/rest.php' ); - RequestContext::getMain()->setTitle( $wgTitle ); + $context->setTitle( $wgTitle ); $services = MediaWikiServices::getInstance(); $conf = $services->getMainConfig(); @@ -42,7 +47,7 @@ class EntryPoint { 'cookiePrefix' => $conf->get( 'CookiePrefix' ) ] ); - $authorizer = new MWBasicAuthorizer( RequestContext::getMain()->getUser(), + $authorizer = new MWBasicAuthorizer( $context->getUser(), $services->getPermissionManager() ); global $IP; @@ -56,21 +61,24 @@ class EntryPoint { ); $entryPoint = new self( + $context, $request, $wgRequest->response(), $router ); $entryPoint->execute(); } - public function __construct( RequestInterface $request, WebResponse $webResponse, - Router $router + public function __construct( RequestContext $context, RequestInterface $request, + WebResponse $webResponse, Router $router ) { + $this->context = $context; $this->request = $request; $this->webResponse = $webResponse; $this->router = $router; } public function execute() { + ob_start(); $response = $this->router->execute( $this->request ); $this->webResponse->header( @@ -91,10 +99,13 @@ class EntryPoint { } // Clear all errors that might have been displayed if display_errors=On - ob_clean(); + ob_end_clean(); $stream = $response->getBody(); $stream->rewind(); + + MediaWiki::preOutputCommit( $this->context ); + if ( $stream instanceof CopyableStreamInterface ) { $stream->copyToStream( fopen( 'php://output', 'w' ) ); } else { @@ -106,5 +117,8 @@ class EntryPoint { echo $buffer; } } + + $mw = new MediaWiki; + $mw->doPostOutputShutdown( 'fast' ); } } diff --git a/tests/phpunit/includes/Rest/EntryPointTest.php b/tests/phpunit/includes/Rest/EntryPointTest.php new file mode 100644 index 0000000000..b599e9d6a4 --- /dev/null +++ b/tests/phpunit/includes/Rest/EntryPointTest.php @@ -0,0 +1,96 @@ +getMockBuilder( WebResponse::class ) + ->setMethods( [ 'header' ] ) + ->getMock(); + } + + public static function mockHandlerHeader() { + return new class extends Handler { + public function execute() { + $response = $this->getResponseFactory()->create(); + $response->setHeader( 'Foo', 'Bar' ); + return $response; + } + }; + } + + public function testHeader() { + $webResponse = $this->createWebResponse(); + $webResponse->expects( $this->any() ) + ->method( 'header' ) + ->withConsecutive( + [ 'HTTP/1.1 200 OK', true, null ], + [ 'Foo: Bar', true, null ] + ); + + $entryPoint = new EntryPoint( + RequestContext::getMain(), + new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/header' ) ] ), + $webResponse, + $this->createRouter() ); + $entryPoint->execute(); + $this->assertTrue( true ); + } + + public static function mockHandlerBodyRewind() { + return new class extends Handler { + public function execute() { + $response = $this->getResponseFactory()->create(); + $stream = new Stream( fopen( 'php://memory', 'w+' ) ); + $stream->write( 'hello' ); + $response->setBody( $stream ); + return $response; + } + }; + } + + /** + * Make sure EntryPoint rewinds a seekable body stream before reading. + */ + public function testBodyRewind() { + $entryPoint = new EntryPoint( + RequestContext::getMain(), + new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/bodyRewind' ) ] ), + $this->createWebResponse(), + $this->createRouter() ); + ob_start(); + $entryPoint->execute(); + $this->assertSame( 'hello', ob_get_clean() ); + } + +} diff --git a/tests/phpunit/unit/includes/Rest/EntryPointTest.php b/tests/phpunit/unit/includes/Rest/EntryPointTest.php deleted file mode 100644 index a74c0cbf20..0000000000 --- a/tests/phpunit/unit/includes/Rest/EntryPointTest.php +++ /dev/null @@ -1,91 +0,0 @@ -getMockBuilder( WebResponse::class ) - ->setMethods( [ 'header' ] ) - ->getMock(); - } - - public static function mockHandlerHeader() { - return new class extends Handler { - public function execute() { - $response = $this->getResponseFactory()->create(); - $response->setHeader( 'Foo', 'Bar' ); - return $response; - } - }; - } - - public function testHeader() { - $webResponse = $this->createWebResponse(); - $webResponse->expects( $this->any() ) - ->method( 'header' ) - ->withConsecutive( - [ 'HTTP/1.1 200 OK', true, null ], - [ 'Foo: Bar', true, null ] - ); - - $entryPoint = new EntryPoint( - new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/header' ) ] ), - $webResponse, - $this->createRouter() ); - $entryPoint->execute(); - $this->assertTrue( true ); - } - - public static function mockHandlerBodyRewind() { - return new class extends Handler { - public function execute() { - $response = $this->getResponseFactory()->create(); - $stream = new Stream( fopen( 'php://memory', 'w+' ) ); - $stream->write( 'hello' ); - $response->setBody( $stream ); - return $response; - } - }; - } - - /** - * Make sure EntryPoint rewinds a seekable body stream before reading. - */ - public function testBodyRewind() { - $entryPoint = new EntryPoint( - new RequestData( [ 'uri' => new Uri( '/rest/mock/EntryPoint/bodyRewind' ) ] ), - $this->createWebResponse(), - $this->createRouter() ); - ob_start(); - $entryPoint->execute(); - $this->assertSame( 'hello', ob_get_clean() ); - } - -}