From 23696bb074e353279c17f6b64fe57ca47e0c2fdf Mon Sep 17 00:00:00 2001 From: "K. Adam White" Date: Tue, 11 Feb 2020 03:22:05 +0000 Subject: [PATCH] REST API: Match REST API routes on namespace before performing regex checks. Rule out groups of API endpoints by simple namespace string comparison to reduce the number of regex checks necessary when matching a route. Props TimothyBlynJacobs. Fixes #48530. Built from https://develop.svn.wordpress.org/trunk@47260 git-svn-id: http://core.svn.wordpress.org/trunk@47060 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/rest-api/class-wp-rest-server.php | 26 ++++++++++++++++--- wp-includes/version.php | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/wp-includes/rest-api/class-wp-rest-server.php b/wp-includes/rest-api/class-wp-rest-server.php index acf23f4dda..efda2321b7 100644 --- a/wp-includes/rest-api/class-wp-rest-server.php +++ b/wp-includes/rest-api/class-wp-rest-server.php @@ -744,11 +744,18 @@ class WP_REST_Server { * used as the delimiter with preg_match() * * @since 4.4.0 + * @since 5.4.0 Add $namespace parameter. * + * @param string $namespace Optionally, only return routes in the given namespace. * @return array `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ), ...)`. */ - public function get_routes() { + public function get_routes( $namespace = '' ) { + $endpoints = $this->endpoints; + + if ( $namespace ) { + $endpoints = wp_list_filter( $endpoints, array( 'namespace' => $namespace ) ); + } /** * Filters the array of available endpoints. @@ -760,7 +767,7 @@ class WP_REST_Server { * `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ). */ - $endpoints = apply_filters( 'rest_endpoints', $this->endpoints ); + $endpoints = apply_filters( 'rest_endpoints', $endpoints ); // Normalise the endpoints. $defaults = array( @@ -872,7 +879,20 @@ class WP_REST_Server { $method = $request->get_method(); $path = $request->get_route(); - foreach ( $this->get_routes() as $route => $handlers ) { + $routes = array(); + + foreach ( $this->get_namespaces() as $namespace ) { + if ( 0 === strpos( ltrim( $path, '/' ), $namespace ) ) { + $routes = $this->get_routes( $namespace ); + break; + } + } + + if ( ! $routes ) { + $routes = $this->get_routes(); + } + + foreach ( $routes as $route => $handlers ) { $match = preg_match( '@^' . $route . '$@i', $path, $matches ); if ( ! $match ) { diff --git a/wp-includes/version.php b/wp-includes/version.php index 568c2a9d55..4e95425bd5 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.4-alpha-47259'; +$wp_version = '5.4-alpha-47260'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.