MediaWiki REL1_31
ParsoidVirtualRESTService.php
Go to the documentation of this file.
1<?php
49 public function __construct( array $params ) {
50 // for backwards compatibility:
51 if ( isset( $params['URL'] ) ) {
52 $params['url'] = $params['URL'];
53 unset( $params['URL'] );
54 }
55 // set up defaults and merge them with the given params
56 $mparams = array_merge( [
57 'name' => 'parsoid',
58 'url' => 'http://localhost:8000/',
59 'prefix' => 'localhost',
60 'domain' => 'localhost',
61 'timeout' => null,
62 'forwardCookies' => false,
63 'HTTPProxy' => null,
64 ], $params );
65 // Ensure that the url parameter has a trailing slash.
66 if ( substr( $mparams['url'], -1 ) !== '/' ) {
67 $mparams['url'] .= '/';
68 }
69 // Ensure the correct domain format: strip protocol, port,
70 // and trailing slash if present. This lets us use
71 // $wgCanonicalServer as a default value, which is very convenient.
72 $mparams['domain'] = preg_replace(
73 '/^(https?:\/\/)?([^\/:]+?)(:\d+)?\/?$/',
74 '$2',
75 $mparams['domain']
76 );
77 parent::__construct( $mparams );
78 }
79
80 public function onRequests( array $reqs, Closure $idGeneratorFunc ) {
81 $result = [];
82 foreach ( $reqs as $key => $req ) {
83 $parts = explode( '/', $req['url'] );
84
85 list(
86 $targetWiki, // 'local'
87 $version, // 'v3' ('v1' for restbase compatibility)
88 $reqType, // 'page' or 'transform'
89 $format, // 'html' or 'wikitext'
90 // $title (optional)
91 // $revision (optional)
92 ) = $parts;
93
94 if ( isset( $this->params['restbaseCompat'] ) && $this->params['restbaseCompat'] ) {
95 if ( $version !== 'v1' ) {
96 throw new Exception( "Only RESTBase v1 API is supported." );
97 }
98 # Map RESTBase v1 API to Parsoid v3 API (pretty easy)
99 $req['url'] = preg_replace( '#^local/v1/#', 'local/v3/', $req['url'] );
100 } elseif ( $version !== 'v3' ) {
101 $result[$key] = $this->onParsoid1Request( $req, $idGeneratorFunc );
102 continue;
103 }
104 if ( $targetWiki !== 'local' ) {
105 throw new Exception( "Only 'local' target wiki is currently supported" );
106 }
107 if ( $reqType !== 'page' && $reqType !== 'transform' ) {
108 throw new Exception( "Request action must be either 'page' or 'transform'" );
109 }
110 if ( $format !== 'html' && $format !== 'wikitext' ) {
111 throw new Exception( "Request format must be either 'html' or 'wt'" );
112 }
113 // replace /local/ with the current domain
114 $req['url'] = preg_replace( '#^local/#', $this->params['domain'] . '/', $req['url'] );
115 // and prefix it with the service URL
116 $req['url'] = $this->params['url'] . $req['url'];
117 // set the appropriate proxy, timeout and headers
118 if ( $this->params['HTTPProxy'] ) {
119 $req['proxy'] = $this->params['HTTPProxy'];
120 }
121 if ( $this->params['timeout'] != null ) {
122 $req['reqTimeout'] = $this->params['timeout'];
123 }
124 if ( $this->params['forwardCookies'] ) {
125 $req['headers']['Cookie'] = $this->params['forwardCookies'];
126 }
127 $result[$key] = $req;
128 }
129 return $result;
130 }
131
154 public function onParsoid1Request( array $req, Closure $idGeneratorFunc ) {
155 $parts = explode( '/', $req['url'] );
156 list(
157 $targetWiki, // 'local'
158 $version, // 'v1'
159 $reqType // 'page' or 'transform'
160 ) = $parts;
161 if ( $targetWiki !== 'local' ) {
162 throw new Exception( "Only 'local' target wiki is currently supported" );
163 } elseif ( $version !== 'v1' ) {
164 throw new Exception( "Only v1 and v3 are supported." );
165 } elseif ( $reqType !== 'page' && $reqType !== 'transform' ) {
166 throw new Exception( "Request type must be either 'page' or 'transform'" );
167 }
168 $req['url'] = $this->params['url'] . $this->params['domain'] . '/v3/';
169 if ( $reqType === 'page' ) {
170 $title = $parts[3];
171 if ( $parts[4] !== 'html' ) {
172 throw new Exception( "Only 'html' output format is currently supported" );
173 }
174 $req['url'] .= 'page/html/' . $title;
175 if ( isset( $parts[5] ) ) {
176 $req['url'] .= '/' . $parts[5];
177 } elseif ( isset( $req['query']['oldid'] ) && $req['query']['oldid'] ) {
178 $req['url'] .= '/' . $req['query']['oldid'];
179 unset( $req['query']['oldid'] );
180 }
181 } elseif ( $reqType === 'transform' ) {
182 $req['url'] .= 'transform/'. $parts[3] . '/to/' . $parts[5];
183 // the title
184 if ( isset( $parts[6] ) ) {
185 $req['url'] .= '/' . $parts[6];
186 }
187 // revision id
188 if ( isset( $parts[7] ) ) {
189 $req['url'] .= '/' . $parts[7];
190 } elseif ( isset( $req['body']['oldid'] ) && $req['body']['oldid'] ) {
191 $req['url'] .= '/' . $req['body']['oldid'];
192 unset( $req['body']['oldid'] );
193 }
194 if ( $parts[4] !== 'to' ) {
195 throw new Exception( "Part index 4 is not 'to'" );
196 }
197 if ( $parts[3] === 'html' && $parts[5] === 'wikitext' ) {
198 if ( !isset( $req['body']['html'] ) ) {
199 throw new Exception( "You must set an 'html' body key for this request" );
200 }
201 } elseif ( $parts[3] == 'wikitext' && $parts[5] == 'html' ) {
202 if ( !isset( $req['body']['wikitext'] ) ) {
203 throw new Exception( "You must set a 'wikitext' body key for this request" );
204 }
205 if ( isset( $req['body']['body'] ) ) {
206 $req['body']['body_only'] = $req['body']['body'];
207 unset( $req['body']['body'] );
208 }
209 } else {
210 throw new Exception( "Transformation unsupported" );
211 }
212 }
213 // set the appropriate proxy, timeout and headers
214 if ( $this->params['HTTPProxy'] ) {
215 $req['proxy'] = $this->params['HTTPProxy'];
216 }
217 if ( $this->params['timeout'] != null ) {
218 $req['reqTimeout'] = $this->params['timeout'];
219 }
220 if ( $this->params['forwardCookies'] ) {
221 $req['headers']['Cookie'] = $this->params['forwardCookies'];
222 }
223
224 return $req;
225 }
226
227}
Virtual HTTP service client for Parsoid.
onRequests(array $reqs, Closure $idGeneratorFunc)
Prepare virtual HTTP(S) requests (for this service) for execution.
__construct(array $params)
Example Parsoid v3 requests: GET /local/v3/page/html/$title/{$revision}.
onParsoid1Request(array $req, Closure $idGeneratorFunc)
Remap a Parsoid v1 request to a Parsoid v3 request.
Virtual HTTP service instance that can be mounted on to a VirtualRESTService.
array $params
Key/value map.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition deferred.txt:11
this hook is for auditing only $req
Definition hooks.txt:990
namespace being checked & $result
Definition hooks.txt:2323
namespace and then decline to actually register it file or subcat img or subcat $title
Definition hooks.txt:964