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.


git-svn-id: https://develop.svn.wordpress.org/trunk@47260 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
K. Adam White
2020-02-11 03:20:05 +00:00
parent 3125c21cc4
commit fc434a0c77
2 changed files with 34 additions and 3 deletions
@@ -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 ) {