3 use Wikimedia\Http\HttpAcceptParser
;
4 use Wikimedia\Http\HttpAcceptNegotiator
;
7 * Request handler implementing a data interface for mediawiki pages.
10 * @author Daniel Kinzler
11 * @author Amir Sarabadanai
14 class PageDataRequestHandler
{
17 * Checks whether the request is complete, i.e. whether it contains all information needed
18 * to reply with page data.
20 * This does not check whether the request is valid and will actually produce a successful
23 * @param string|null $title Page title
24 * @param WebRequest $request
29 public function canHandleRequest( $title, WebRequest
$request ) {
30 if ( $title === '' ||
$title === null ) {
31 if ( $request->getText( 'target', '' ) === '' ) {
40 * Main method for handling requests.
42 * @param string $title Page title
43 * @param WebRequest $request The request parameters. Known parameters are:
44 * - title: the page title
45 * - format: the format
46 * - oldid|revision: the revision ID
47 * @param OutputPage $output
49 * @note: Instead of an output page, a WebResponse could be sufficient, but
50 * redirect logic is currently implemented in OutputPage.
54 public function handleRequest( $title, WebRequest
$request, OutputPage
$output ) {
55 // No matter what: The response is always public
56 $output->getRequest()->response()->header( 'Access-Control-Allow-Origin: *' );
60 $title = $request->getText( 'target', $title );
61 $revision = $request->getInt( 'oldid', $revision );
62 $revision = $request->getInt( 'revision', $revision );
64 if ( $title === null ||
$title === '' ) {
65 //TODO: different error message?
66 throw new HttpError( 400, wfMessage( 'pagedata-bad-title', $title ) );
70 $title = Title
::newFromTextThrow( $title );
71 } catch ( MalformedTitleException
$ex ) {
72 throw new HttpError( 400, wfMessage( 'pagedata-bad-title', $title ) );
75 $this->httpContentNegotiation( $request, $output, $title, $revision );
79 * Applies HTTP content negotiation.
80 * If the negotiation is successful, this method will set the appropriate redirect
81 * in the OutputPage object and return. Otherwise, an HttpError is thrown.
83 * @param WebRequest $request
84 * @param OutputPage $output
86 * @param int $revision The desired revision
90 public function httpContentNegotiation(
96 $contentHandler = ContentHandler
::getForTitle( $title );
97 $mimeTypes = $contentHandler->getSupportedFormats();
99 $headers = $request->getAllHeaders();
100 if ( isset( $headers['ACCEPT'] ) ) {
101 $parser = new HttpAcceptParser();
102 $accept = $parser->parseWeights( $headers['ACCEPT'] );
106 '*' => 0.1 // just to make extra sure
108 // prefer the default
109 $accept[$mimeTypes[0]] = 1;
112 $negotiator = new HttpAcceptNegotiator( $mimeTypes );
113 $format = $negotiator->getBestSupportedKey( $accept, null );
115 if ( $format === null ) {
116 $format = isset( $accept['text/html'] ) ?
'text/html' : null;
119 if ( $format === null ) {
120 $msg = wfMessage( 'pagedata-not-acceptable', implode( ', ', $mimeTypes ) );
121 throw new HttpError( 406, $msg );
124 $url = $this->getDocUrl( $title, $format, $revision );
125 $output->redirect( $url, 303 );
129 * Returns a url representing the given title.
131 * @param Title $title
132 * @param string|null $format The (normalized) format name, or ''
133 * @param int $revision
136 private function getDocUrl( Title
$title, $format = '', $revision = 0 ) {
139 if ( $revision > 0 ) {
140 $params['oldid'] = $revision;
143 if ( $format === 'text/html' ) {
144 return $title->getFullURL( $params );
147 $params[ 'action' ] = 'raw';
149 return $title->getFullURL( $params );