WC_REST_Authentication::route_from_request_uri
The REST route the request URI points to, normalized the way WordPress matches it.
Returns the route without the REST prefix or surrounding slashes, e.g. 'wc/v3/products'. The path is read unconditionally; a route named in the query string is only trusted once wp_is_rest_endpoint() confirms genuine REST dispatch, and returns an empty string until then.
Method of the class: WC_REST_Authentication{}
No Hooks.
Returns
string.
Usage
// private - for code of main (parent) class only $result = $this->route_from_request_uri();
Changelog
| Since 11.1.0 | Introduced. |
WC_REST_Authentication::route_from_request_uri() WC REST Authentication::route from request uri code WC 11.1.2
private function route_from_request_uri() {
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
return '';
}
$rest_prefix = trailingslashit( rest_get_url_prefix() );
/*
* Parse the raw URI, not an esc_url_raw() copy. This decides whether an API key may
* authenticate the request, so it has to read the URI the way WordPress routes on it.
* esc_url_raw() rewrites its input, so the route derived from an escaped copy is not always
* the route that gets served. Only parsed and compared here, never output, so no escaping is
* needed.
*/
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Parsed and compared against REST route prefixes only, never output or stored; sanitizing would diverge from the route WordPress dispatches.
$request_uri = wp_unslash( $_SERVER['REQUEST_URI'] );
// WP::parse_request() trims leading slashes off the URI, but wp_parse_url() would read a
// leading '//' as a host, so collapse them first.
if ( str_starts_with( $request_uri, '//' ) ) {
$request_uri = '/' . ltrim( $request_uri, '/' );
}
$query_string = wp_parse_url( $request_uri, PHP_URL_QUERY );
$query_params = array();
if ( is_string( $query_string ) ) {
parse_str( $query_string, $query_params );
}
// Plain permalinks can carry the route in the query string.
if ( isset( $query_params['rest_route'] ) ) {
// Only trust and read it once dispatch is confirmed and it's a single value.
if ( ! wp_is_rest_endpoint() || ! is_string( $query_params['rest_route'] ) ) {
return '';
}
return trim( $query_params['rest_route'], '/' );
}
$request_path = wp_parse_url( $request_uri, PHP_URL_PATH );
if ( ! is_string( $request_path ) ) {
return '';
}
// Strip the site's home path the way WP::parse_request() does, so subdirectory installs
// resolve to the same path WordPress matches its rewrite rules against.
$request_path = trim( $request_path, '/' );
$home_path = wp_parse_url( home_url(), PHP_URL_PATH );
if ( is_string( $home_path ) && '' !== $home_path ) {
$home_path = trim( $home_path, '/' );
if ( 0 === stripos( $request_path, $home_path ) ) {
$request_path = trim( substr( $request_path, strlen( $home_path ) ), '/' );
}
}
if ( str_starts_with( $request_path, 'index.php/' ) ) {
$request_path = substr( $request_path, strlen( 'index.php/' ) );
}
// Pretty permalinks carry the route after the REST prefix; anything else is not a REST request.
if ( ! str_starts_with( $request_path, $rest_prefix ) ) {
return '';
}
return trim( substr( $request_path, strlen( $rest_prefix ) ), '/' );
}