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
namespace MediaWiki\Rest;
use ExtensionRegistry;
+use MediaWiki;
use MediaWiki\MediaWikiServices;
use MediaWiki\Rest\BasicAccess\MWBasicAuthorizer;
use RequestContext;
private $webResponse;
/** @var Router */
private $router;
+ /** @var RequestContext */
+ private $context;
public static function main() {
// URL safety checks
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();
'cookiePrefix' => $conf->get( 'CookiePrefix' )
] );
- $authorizer = new MWBasicAuthorizer( RequestContext::getMain()->getUser(),
+ $authorizer = new MWBasicAuthorizer( $context->getUser(),
$services->getPermissionManager() );
global $IP;
);
$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(
}
// 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 {
echo $buffer;
}
}
+
+ $mw = new MediaWiki;
+ $mw->doPostOutputShutdown( 'fast' );
}
}
--- /dev/null
+<?php
+
+namespace MediaWiki\Tests\Rest;
+
+use EmptyBagOStuff;
+use GuzzleHttp\Psr7\Uri;
+use GuzzleHttp\Psr7\Stream;
+use MediaWiki\Rest\BasicAccess\StaticBasicAuthorizer;
+use MediaWiki\Rest\Handler;
+use MediaWiki\Rest\EntryPoint;
+use MediaWiki\Rest\RequestData;
+use MediaWiki\Rest\ResponseFactory;
+use MediaWiki\Rest\Router;
+use RequestContext;
+use WebResponse;
+
+/**
+ * @covers \MediaWiki\Rest\EntryPoint
+ * @covers \MediaWiki\Rest\Router
+ */
+class EntryPointTest extends \MediaWikiTestCase {
+ private static $mockHandler;
+
+ private function createRouter() {
+ global $IP;
+
+ return new Router(
+ [ "$IP/tests/phpunit/unit/includes/Rest/testRoutes.json" ],
+ [],
+ '/rest',
+ new EmptyBagOStuff(),
+ new ResponseFactory(),
+ new StaticBasicAuthorizer() );
+ }
+
+ private function createWebResponse() {
+ return $this->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() );
+ }
+
+}
+++ /dev/null
-<?php
-
-namespace MediaWiki\Tests\Rest;
-
-use EmptyBagOStuff;
-use GuzzleHttp\Psr7\Uri;
-use GuzzleHttp\Psr7\Stream;
-use MediaWiki\Rest\BasicAccess\StaticBasicAuthorizer;
-use MediaWiki\Rest\Handler;
-use MediaWiki\Rest\EntryPoint;
-use MediaWiki\Rest\RequestData;
-use MediaWiki\Rest\ResponseFactory;
-use MediaWiki\Rest\Router;
-use WebResponse;
-
-/**
- * @covers \MediaWiki\Rest\EntryPoint
- * @covers \MediaWiki\Rest\Router
- */
-class EntryPointTest extends \MediaWikiUnitTestCase {
- private static $mockHandler;
-
- private function createRouter() {
- return new Router(
- [ __DIR__ . '/testRoutes.json' ],
- [],
- '/rest',
- new EmptyBagOStuff(),
- new ResponseFactory(),
- new StaticBasicAuthorizer() );
- }
-
- private function createWebResponse() {
- return $this->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() );
- }
-
-}