11use Wikimedia\ObjectFactory;
86 $cacheData = $this->cacheBag->get( $this->
getCacheKey() );
87 if ( $cacheData && $cacheData[
'CONFIG-HASH'] === $this->
getConfigHash() ) {
88 unset( $cacheData[
'CONFIG-HASH'] );
99 return $this->cacheBag->makeKey( __CLASS__,
'1' );
108 if ( $this->configHash ===
null ) {
109 $this->configHash = md5( json_encode( [
123 if ( $this->routesFromFiles ===
null ) {
124 $this->routeFileTimestamps = [];
125 foreach ( $this->routeFiles as $fileName ) {
126 $this->routeFileTimestamps[$fileName] = filemtime( $fileName );
127 $routes = json_decode( file_get_contents( $fileName ),
true );
128 if ( $this->routesFromFiles ===
null ) {
129 $this->routesFromFiles = $routes;
131 $this->routesFromFiles = array_merge( $this->routesFromFiles, $routes );
144 if ( $this->routeFileTimestamps ===
null ) {
145 $this->routeFileTimestamps = [];
146 foreach ( $this->routeFiles as $fileName ) {
147 $this->routeFileTimestamps[$fileName] = filemtime( $fileName );
160 $iterator =
new AppendIterator;
162 $iterator->append(
new \ArrayIterator( $this->extraRoutes ) );
172 if ( $this->matchers ===
null ) {
176 foreach ( $cacheData as $method => $data ) {
181 $methods = $spec[
'method'] ?? [
'GET' ];
182 if ( !is_array( $methods ) ) {
183 $methods = [ $methods ];
185 foreach ( $methods as $method ) {
194 foreach (
$matchers as $method => $matcher ) {
195 $cacheData[$method] = $matcher->getCacheData();
197 $this->cacheBag->set( $this->
getCacheKey(), $cacheData );
212 if ( strlen( $this->rootPath ) > strlen(
$path ) ||
213 substr_compare(
$path, $this->rootPath, 0, strlen( $this->rootPath ) ) !== 0
217 return substr(
$path, strlen( $this->rootPath ) );
229 if ( $relPath ===
false ) {
230 return $this->responseFactory->createLocalizedHttpError( 404,
232 ->plaintextParams(
$path, $this->rootPath )
238 $matcher =
$matchers[$requestMethod] ??
null;
239 $match = $matcher ? $matcher->
match( $relPath ) :
null;
243 if ( !$match && $requestMethod ===
'HEAD' && isset(
$matchers[
'GET'] ) ) {
250 foreach (
$matchers as $allowedMethod => $allowedMatcher ) {
251 if ( $allowedMethod === $requestMethod ) {
254 if ( $allowedMatcher->match( $relPath ) ) {
255 $allowed[] = $allowedMethod;
259 $response = $this->responseFactory->createLocalizedHttpError( 405,
261 ->textParams( $requestMethod )
262 ->commaListParams( $allowed )
263 ->numParams( count( $allowed ) )
265 $response->setHeader(
'Allow', $allowed );
269 return $this->responseFactory->createLocalizedHttpError( 404,
271 ->plaintextParams( $relPath )
276 $request->
setPathParams( array_map(
'rawurldecode', $match[
'params'] ) );
277 $spec = $match[
'userData'];
278 $objectFactorySpec = array_intersect_key( $spec,
279 [
'factory' =>
true,
'class' =>
true,
'args' =>
true,
'services' =>
true ] );
281 $handler = $this->objectFactory->createObject( $objectFactorySpec );
282 $handler->init( $this, $request, $spec, $this->responseFactory );
287 return $this->responseFactory->createFromException( $e );
299 $authResult = $this->basicAuth->authorize( $handler->getRequest(), $handler );
301 return $this->responseFactory->createHttpError( 403, [
'error' => $authResult ] );
304 $handler->validate( $this->restValidator );
Class representing a cache/ephemeral data store.