getText( 'title', '' ) === '' ) { return false; } } return true; } /** * Main method for handling requests. * * @param string $title Page title * @param WebRequest $request The request parameters. Known parameters are: * - title: the page title * - format: the format * - oldid|revision: the revision ID * @param OutputPage $output * * @note: Instead of an output page, a WebResponse could be sufficient, but * redirect logic is currently implemented in OutputPage. * * @throws HttpError */ public function handleRequest( $title, WebRequest $request, OutputPage $output ) { // No matter what: The response is always public $output->getRequest()->response()->header( 'Access-Control-Allow-Origin: *' ); $revision = 0; $title = $request->getText( 'title', $title ); $revision = $request->getInt( 'oldid', $revision ); $revision = $request->getInt( 'revision', $revision ); if ( $title === null || $title === '' ) { //TODO: different error message? throw new HttpError( 400, wfMessage( 'pagedata-bad-title', $title ) ); } try { $title = Title::newFromTextThrow( $title ); } catch ( MalformedTitleException $ex ) { throw new HttpError( 400, wfMessage( 'pagedata-bad-title', $title ) ); } $this->httpContentNegotiation( $request, $output, $title, $revision ); } /** * Applies HTTP content negotiation. * If the negotiation is successful, this method will set the appropriate redirect * in the OutputPage object and return. Otherwise, an HttpError is thrown. * * @param WebRequest $request * @param OutputPage $output * @param Title $title * @param int $revision The desired revision * * @throws HttpError */ public function httpContentNegotiation( WebRequest $request, OutputPage $output, Title $title, $revision = 0 ) { $contentHandler = ContentHandler::getForTitle( $title ); $mimeTypes = $contentHandler->getSupportedFormats(); $headers = $request->getAllHeaders(); if ( isset( $headers['ACCEPT'] ) ) { $parser = new HttpAcceptParser(); $accept = $parser->parseWeights( $headers['ACCEPT'] ); } else { // anything goes $accept = [ '*' => 0.1 // just to make extra sure ]; // prefer the default $accept[$mimeTypes[0]] = 1; } $negotiator = new HttpAcceptNegotiator( $mimeTypes ); $format = $negotiator->getBestSupportedKey( $accept, null ); if ( $format === null ) { $format = isset( $accept['text/html'] ) ? 'text/html' : null; } if ( $format === null ) { $msg = wfMessage( 'pagedata-not-acceptable', implode( ', ', $mimeTypes ) ); throw new HttpError( 406, $msg ); } $url = $this->getDocUrl( $title, $format, $revision ); $output->redirect( $url, 303 ); } /** * Returns a url representing the given title. * * @param Title $title * @param string|null $format The (normalized) format name, or '' * @param int $revision * @return string */ private function getDocUrl( Title $title, $format = '', $revision = 0 ) { $params = []; if ( $revision > 0 ) { $params['oldid'] = $revision; } if ( $format === 'text/html' ) { return $title->getFullURL( $params ); } $params[ 'action' ] = 'raw'; return $title->getFullURL( $params ); } }