web-dev-qa-db-fra.com

option register_rest_route regex pour base64 ou alternative

Ce que j'ai testé

Version Wordpress : 4.9.5

PHP Version : 7.1.7/7.1.4/7.2.0/7.0.3/5.6.20/5.5.38/5.4.45

Serveur Web : Nginx 1.10.1/Apache 2.4.10

Environment/Host : Flywheel local https://local.getflywheel.com/

Version de la bibliothèque PCRE : 8.38 2015-11-23

J'ai essayé de travailler avec register_rest_route mais je rencontrais des problèmes de regex. Il semble qu'il y ait un filtrage sur la regex avant son exécution.

La fonction que j'essaie de créer est de saisir un message par le lien permanent. Fondamentalement, j'ai un client qui structure son URL similaire à wordpress afin qu'il souhaite passer le lien permanent à wordpress afin que je puisse obtenir les données de publication

register_rest_route( $this->namespace, '/post_by_permalink/(?P<path>[\w-]+)', array(
   'methods'             => WP_REST_Server::READABLE,
   'callback'            => array( $this, 'postByPermalink' ),
   'permission_callback' => array( $this, 'permissions' ),
   'show_in_rest' => true
));

C’est la fonction que j’utilise et qui fonctionne dans certains cas. Cependant, c'est uniquement parce que ceux qui fonctionnent ne génèrent aucun caractère spécial.

À l’heure actuelle, mon plan consistait à convertir le permalien en base64 afin de faciliter le passage de l’URL, bien que je sois ouvert aux suggestions s’ils fonctionnent (je n’ai pensé qu’à base64, car urlencode était encore plus cauchemardesque).

Fondamentalement, le seul regex qui fonctionne dans wordpress semble être (?P<path>[\w-]+) et (?P<path>[\d]+). Tout le reste ne fonctionne pas, même s'il a réussi à le tester dans quelque chose comme http://www.phpliveregex.com

Par exemple, selon le testeur (?P<path>[\S]+) devrait fonctionner, mais tout ce que je reçois de wordpress est rest_no_route

Y a-t-il un moyen pour que WordPress gère normalement regex? Ou au moins lui dire de permettre une expression qui pourrait attraper base64? J'ai vu quelques options en ligne, mais aucune ne fonctionne, probablement en raison de changements dans le repos de wp au fil du temps (tous disent "utilisez simplement regex", mais cela semble filtrer les regex plus complexes)

EDIT: exemple étendu

app/v1/post_by_permalink/(?P<path>[\S-]+)

Est ce qui fonctionnera dans http://www.phpliveregex.com

La chaîne de recherche étant

/wp-json/app/v1/post_by_permalink/dGVzdC90ZXN0

Cette même expression rationnelle ne fonctionnera pas dans wordpress, seul (?P<path>[\w-]+) fonctionnera. Pour l'exemple ci-dessus, cela fonctionnera également dans les deux cas, car il n'y a pas de caractères spéciaux.

Toutefois, pour cette chaîne, il ne sera pas

/wp-json/app/v1/post_by_permalink/dGVzdC90ZXN0LzM1NzM0Ly0=

Puisqu'il a un = Ainsi, bien que dans le testeur de regex (?P<path>[\S]+) fonctionne, cela ne fonctionnera pas dans wordpress.

Edit: autres tests

J'ai réussi à rechercher rest_pre_dispatch et à le faire fonctionner pour intercepter la demande avant qu'il ne vérifie les itinéraires.

add_filter('rest_pre_dispatch', 'filter_request');
function filter_request($result) {
    global $wp;

    //print_r($wp->request); die;
    preg_match("/app\/v1\/post_by_permalink\/(?P<path>[\S]+)/", $wp->request, $output);
    print_r($output); die;
    return $result;
}

Est capable de définir le chemin correctement, donc cela ne semble pas être un problème avec preg_match. Au moins, avec cela, je peux contourner wp-rest et contourner ce problème, mais je n’ai toujours pas trouvé la cause réelle de tous les environnements dans lesquels j’essayais d’échouer, et pourtant personne d’autre ne peut le recréer .....

Après des tests plus approfondis, le fonctionnement ci-dessous a fonctionné. J'utilisais $wp->request qui incluait wp-json et qui causait l'échec de la regex.

Cependant, lorsque j'utilise preg_match( '@^' . $route . '$@i', $path, $matches ), je ne parviens pas à le faire fonctionner (c’est ainsi que wp-rest le fait, $ route étant ce qui est passé par register_rest_route), et utiliser preg_match de cette manière n’est pas pris en charge dans le testeur de regex http: //. www.phpliveregex.com/ soit. Il ajoute plus de questions puis de réponses.

1
Jordan Ramstad

Je suis devenu curieux, alors j'ai testé cette démo barebone:

add_action( 'rest_api_init', function () {
    register_rest_route( 'wpse/v1', '/post_by_permalink/(?P<path>[\S]+)', [
        'methods'      => WP_REST_Server::READABLE,
        'callback'     => 'wpse_callback',
        'show_in_rest' => true
    ] );
});

function wpse_callback( $request ) {
    $data = [ 'path' => base64_decode( $request['path'] ) ];
    return $data;
}

Essai:

https://example.com/wp-json/wpse/v1/post_by_permalink/aHR0cHM6Ly93b3JkcHJlc3Muc3RhY2tleGNoYW5nZS5jb20vcS8zMDEwNjcv

donne

{
   path: "https://wordpress.stackexchange.com/q/301067/"
}

Testé aussi

https://example.com/wp-json/wpse/v1/post_by_permalink/aHR0cHM6Ly93b3JkcHJlc3Muc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzMwMTA2Ny9yZWdpc3Rlci1yZXN0LXJvdXRlLXJlZ2V4LW9wdGlvbi1mb3ItYmFzZTY0LW9yLWFsdGVybmF0ZS8zMDEwNzY=

cela a donné:

{
path: "https://wordpress.stackexchange.com/questions/301067/register-rest-route-regex-option-for-base64-or-alternate/301076"
}

Testé plus loin:

https://example.com/wp-json/wpse/v1/post_by_permalink/dGVzdC90ZXN0LzM1NzM0Ly0=

avec sortie:

{
path: "test/test/35734/-"
}
1
birgire

Finalement, j'ai compris, et je ne peux que m'en vouloir.

Lors de mes tests, j'avais désactivé tous les plugins, mais pendant ce temps, je l'avais laissé en utilisant (?P<path>[\w-]+) lors du test avec une chaîne base64 contenant un =. Pendant tout ce temps, j'avais éliminé les plugins car je pensais l'avoir recréé malgré l'absence de plugins actifs.

Le coupable était Rest Managerhttps://wordpress.org/plugins/rest-manager/

J'ai ouvert un ticket de support pour informer le développeur.

Il utilise rest_pre_dispatch pour filtrer les routes que vous avez définies comme étant inactives. Le problème est que si vous modifiez les routes, vous devez entrer et réenregistrer la configuration. Heureusement, il était réparable car il contenait un crochet avant de filtrer les routes. Je pouvais donc "réparer" la fonction et supposer que les routes sans configuration devaient être activées par défaut.

Merci à @mmm, @birire et @Otto d'avoir pris le temps d'essayer de recréer le problème.

Désactiver les plugins lorsque vous essayez d'isoler un problème enfants ;-)

1
Jordan Ramstad