MediaWiki REL1_31
RestbaseVirtualRESTService.php
Go to the documentation of this file.
1<?php
51 public function __construct( array $params ) {
52 // set up defaults and merge them with the given params
53 $mparams = array_merge( [
54 'name' => 'restbase',
55 'url' => 'http://localhost:7231/',
56 'domain' => 'localhost',
57 'timeout' => 100,
58 'forwardCookies' => false,
59 'HTTPProxy' => null,
60 'parsoidCompat' => false,
61 'fixedUrl' => false,
62 ], $params );
63 // Ensure that the url parameter has a trailing slash.
64 if ( substr( $mparams['url'], -1 ) !== '/' ) {
65 $mparams['url'] .= '/';
66 }
67 // Ensure the correct domain format: strip protocol, port,
68 // and trailing slash if present. This lets us use
69 // $wgCanonicalServer as a default value, which is very convenient.
70 $mparams['domain'] = preg_replace(
71 '/^(https?:\/\/)?([^\/:]+?)(:\d+)?\/?$/',
72 '$2',
73 $mparams['domain']
74 );
75 parent::__construct( $mparams );
76 }
77
78 public function onRequests( array $reqs, Closure $idGenFunc ) {
79 if ( $this->params['parsoidCompat'] ) {
80 return $this->onParsoidRequests( $reqs, $idGenFunc );
81 }
82
83 $result = [];
84 foreach ( $reqs as $key => $req ) {
85 if ( $this->params['fixedUrl'] ) {
86 $version = explode( '/', $req['url'] )[1];
87 $req['url'] =
88 str_replace( '#version#', $version, $this->params['url'] ) .
89 preg_replace( '#^local/v./#', '', $req['url'] );
90 } else {
91 // replace /local/ with the current domain
92 $req['url'] = preg_replace( '#^local/#', $this->params['domain'] . '/', $req['url'] );
93 // and prefix it with the service URL
94 $req['url'] = $this->params['url'] . $req['url'];
95 }
96
97 // set the appropriate proxy, timeout and headers
98 if ( $this->params['HTTPProxy'] ) {
99 $req['proxy'] = $this->params['HTTPProxy'];
100 }
101 if ( $this->params['timeout'] != null ) {
102 $req['reqTimeout'] = $this->params['timeout'];
103 }
104 if ( $this->params['forwardCookies'] ) {
105 $req['headers']['Cookie'] = $this->params['forwardCookies'];
106 }
107 $result[$key] = $req;
108 }
109
110 return $result;
111 }
112
120 public function onParsoidRequests( array $reqs, Closure $idGeneratorFunc ) {
121 $result = [];
122 foreach ( $reqs as $key => $req ) {
123 $version = explode( '/', $req['url'] )[1];
124 if ( $version === 'v3' ) {
125 $result[$key] = $this->onParsoid3Request( $req, $idGeneratorFunc );
126 } elseif ( $version === 'v1' ) {
127 $result[$key] = $this->onParsoid1Request( $req, $idGeneratorFunc );
128 } else {
129 throw new Exception( "Only v1 and v3 are supported." );
130 }
131 }
132
133 return $result;
134 }
135
157 public function onParsoid1Request( array $req, Closure $idGeneratorFunc ) {
158 $parts = explode( '/', $req['url'] );
159 list(
160 $targetWiki, // 'local'
161 $version, // 'v1'
162 $reqType // 'page' or 'transform'
163 ) = $parts;
164 if ( $targetWiki !== 'local' ) {
165 throw new Exception( "Only 'local' target wiki is currently supported" );
166 } elseif ( $version !== 'v1' ) {
167 throw new Exception( "Version mismatch: should not happen." );
168 } elseif ( $reqType !== 'page' && $reqType !== 'transform' ) {
169 throw new Exception( "Request type must be either 'page' or 'transform'" );
170 }
171 $req['url'] = $this->params['url'] . $this->params['domain'] . '/v1/' . $reqType . '/';
172 if ( $reqType === 'page' ) {
173 $title = $parts[3];
174 if ( $parts[4] !== 'html' ) {
175 throw new Exception( "Only 'html' output format is currently supported" );
176 }
177 $req['url'] .= 'html/' . $title;
178 if ( isset( $parts[5] ) ) {
179 $req['url'] .= '/' . $parts[5];
180 } elseif ( isset( $req['query']['oldid'] ) && $req['query']['oldid'] ) {
181 $req['url'] .= '/' . $req['query']['oldid'];
182 unset( $req['query']['oldid'] );
183 }
184 } elseif ( $reqType === 'transform' ) {
185 // from / to transform
186 $req['url'] .= $parts[3] . '/to/' . $parts[5];
187 // the title
188 if ( isset( $parts[6] ) ) {
189 $req['url'] .= '/' . $parts[6];
190 }
191 // revision id
192 if ( isset( $parts[7] ) ) {
193 $req['url'] .= '/' . $parts[7];
194 } elseif ( isset( $req['body']['oldid'] ) && $req['body']['oldid'] ) {
195 $req['url'] .= '/' . $req['body']['oldid'];
196 unset( $req['body']['oldid'] );
197 }
198 if ( $parts[4] !== 'to' ) {
199 throw new Exception( "Part index 4 is not 'to'" );
200 }
201 if ( $parts[3] === 'html' && $parts[5] === 'wikitext' ) {
202 if ( !isset( $req['body']['html'] ) ) {
203 throw new Exception( "You must set an 'html' body key for this request" );
204 }
205 } elseif ( $parts[3] == 'wikitext' && $parts[5] == 'html' ) {
206 if ( !isset( $req['body']['wikitext'] ) ) {
207 throw new Exception( "You must set a 'wikitext' body key for this request" );
208 }
209 if ( isset( $req['body']['body'] ) ) {
210 $req['body']['body_only'] = $req['body']['body'];
211 unset( $req['body']['body'] );
212 }
213 } else {
214 throw new Exception( "Transformation unsupported" );
215 }
216 }
217 // set the appropriate proxy, timeout and headers
218 if ( $this->params['HTTPProxy'] ) {
219 $req['proxy'] = $this->params['HTTPProxy'];
220 }
221 if ( $this->params['timeout'] != null ) {
222 $req['reqTimeout'] = $this->params['timeout'];
223 }
224 if ( $this->params['forwardCookies'] ) {
225 $req['headers']['Cookie'] = $this->params['forwardCookies'];
226 }
227
228 return $req;
229 }
230
249 public function onParsoid3Request( array $req, Closure $idGeneratorFunc ) {
250 $parts = explode( '/', $req['url'] );
251 list(
252 $targetWiki, // 'local'
253 $version, // 'v3'
254 $action, // 'transform' or 'page'
255 $format, // 'html' or 'wikitext'
256 // $title, // optional
257 // $revision, // optional
258 ) = $parts;
259 if ( $targetWiki !== 'local' ) {
260 throw new Exception( "Only 'local' target wiki is currently supported" );
261 } elseif ( $version !== 'v3' ) {
262 throw new Exception( "Version mismatch: should not happen." );
263 }
264 // replace /local/ with the current domain, change v3 to v1,
265 $req['url'] = preg_replace( '#^local/v3/#', $this->params['domain'] . '/v1/', $req['url'] );
266 // and prefix it with the service URL
267 $req['url'] = $this->params['url'] . $req['url'];
268 // set the appropriate proxy, timeout and headers
269 if ( $this->params['HTTPProxy'] ) {
270 $req['proxy'] = $this->params['HTTPProxy'];
271 }
272 if ( $this->params['timeout'] != null ) {
273 $req['reqTimeout'] = $this->params['timeout'];
274 }
275 if ( $this->params['forwardCookies'] ) {
276 $req['headers']['Cookie'] = $this->params['forwardCookies'];
277 }
278
279 return $req;
280 }
281
282}
Virtual HTTP service client for RESTBase.
onRequests(array $reqs, Closure $idGenFunc)
Prepare virtual HTTP(S) requests (for this service) for execution.
onParsoid1Request(array $req, Closure $idGeneratorFunc)
Remap a Parsoid v1 request to a RESTBase v1 request.
onParsoidRequests(array $reqs, Closure $idGeneratorFunc)
Remaps Parsoid v1/v3 requests to RESTBase v1 requests.
onParsoid3Request(array $req, Closure $idGeneratorFunc)
Remap a Parsoid v3 request to a RESTBase v1 request.
__construct(array $params)
Example RESTBase v1 requests: GET /local/v1/page/html/{title}{/revision} POST /local/v1/transform/htm...
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