Je souhaite filtrer tout URI de requête HTTP effectué via l'API HTTP.
Cas d'utilisation:
- La vérification de la mise à jour de WordPress va à http://api.wordpress.org/core/version-check/1.6/ , mais https://api.wordpress.org/core/version-check/1.6/ fonctionne aussi, et je veux pour l'utiliser toujours.
- Le nouveau fichier WordPress est extrait de http://wordpress.org/wordpress-3.4.2.zip , mais https://wordpress.org/wordpress-3.4.2.zip fonctionne également.
- Parfois, je veux déboguer les demandes et rediriger celles temporaires vers un domaine personnalisé sur mon serveur local.
- Certains plugins font des requêtes à d'autres serveurs, et je veux remplacer ces requêtes lorsque le serveur externe tombe en panne.
Les demandes de mise à jour sont les plus importantes pour l'instant, car il y a toujours le bogue non corrigé 16778 ( plus d'informations ), et les demandes HTTPS réduisent le risque d'une attaque de type Man-in-the-middle.
J'ai cherché en profondeur , j'ai étudié le code de base… mais j'ai fini comme Nacin il y a deux ans:
Je pensais à coup sûr que vous pouviez filtrer l'URL d'une demande HTTP, mais maintenant je n'en trouve plus.
Qu'est-ce que j'ai raté? Ai-je? :)
Réponses:
Moins qu'une réponse, mais juste une liste de choses directement tirées de mon expérience avec elle - peut-être que vous avez oublié quelque chose.
Débogage de la requête et de ses résultats
Sans creuser trop profondément dans le processus de mise à jour, mais l'API WP HTTP utilise la
WP_HTTP
classe. Il offre également une bonne chose: un crochet de débogage.Où
$response
peut aussi être unWP_Error
objet qui vous en dit peut-être plus.Remarque: à partir d'un bref test, ce filtre semble ne fonctionner (pour une raison quelconque) que si vous le placez aussi près de l'endroit où vous effectuez réellement la demande. Alors peut-être que vous devez l'appeler à partir d'un rappel sur l'un des filtres ci-dessous.
WP_HTTP
Arguments de classeLes arguments Classes lui-même sont filtrables, mais certains afaik sont réinitialisés par les méthodes internes à ce que WP suppose être nécessaire.
L'un des arguments est
ssl_verify
, ce qui est vrai par défaut (mais pour moi, cela pose d'énormes problèmes lors de la mise à jour depuis - par exemple - GitHub). Edit: Après avoir débogué une demande de test, j'ai trouvé un autre argument qui est défini pour vérifier si SSL est défini surtrue
. Il est appelésslverify
(sans séparer le trait de soulignement). Aucune idée d'où cela est entré dans le jeu, s'il est réellement utilisé ou abandonné et si vous avez une chance d'influencer sa valeur. Je l'ai trouvé en utilisant le'http_api_debug'
filtre.Complètement personnalisé
Vous pouvez également "simplement" remplacer tous les composants internes et opter pour une configuration personnalisée. Il y a un filtre pour ça.
Le premier argument doit être défini sur true. Ensuite, vous pouvez interagir avec les arguments à l'intérieur
$r
et le résultat deparse_url( $url );
.Procuration
Une autre chose qui pourrait fonctionner pourrait être de tout exécuter via un proxy personnalisé. Cela nécessite quelques paramètres dans votre
wp-config.php
. Je n'ai jamais essayé cela auparavant, mais j'ai parcouru les constantes il y a quelque temps et j'ai résumé quelques exemples qui devraient fonctionner et inclus quelques commentaires au cas où j'en aurais besoin un jour. Vous devez définirWP_PROXY_HOST
et enWP_PROXY_PORT
tant que min. réglage. Sinon, rien ne fonctionnera et il contournera simplement votre proxy.ÉDITER
La
WP_HTTP
classe agit normalement comme classe de base (sera étendue pour différents scénarios). Les étendant lesWP_HTTP_*
classes sontFsockopen
,Streams
,Curl
,Proxy
,Cookie
,Encoding
. Si vous accrochez un rappel à l''http_api_debug'
action, le troisième argument vous indiquera quelle classe a été utilisée pour votre demande.À l'intérieur de la
WP_HTTP_curl
classe, vous trouverez larequest()
méthode. Cette méthode propose deux filtres pour intercepter le comportement SSL: un pour les requêtes locales'https_local_ssl_verify'
et un pour les requêtes distantes'https_ssl_verify'
. WP définira probablement aulocal
furlocalhost
et à mesure ce que vous obtenez en retourget_option( 'siteurl' );
.Donc, ce que je ferais, c'est d'essayer ce qui suit juste avant de faire cette demande (ou à partir d'un rappel lié à la demande la plus proche:
Sidenote: Dans la plupart des cas,
WP_HTTP_curl
sera utilisé pour gérer les procurations.la source
pre_http_request
, annuler la demande et la renvoyer avec l'URL correcte. Je vais essayer ça ce soir.Sur la base de la réponse utile de @ kaiser, j'ai écrit du code qui semble bien fonctionner. C'est la raison pour laquelle je l'ai marqué comme réponse.
Laissez-moi vous expliquer ma solution…
La logique
Lorsqu'une demande envoyée via l'API est exécutée
WP_Http::request()
. C'est la méthode avec…… Dans son en-tête. Je ne pourrais pas être plus d'accord.
Maintenant, il y a des filtres. J'ai décidé d'abuser
pre_http_request
de mes besoins:Nous obtenons trois arguments ici:
false, $r, $url
.false
est la valeur de retour attendue pourapply_filters()
. Si nous renvoyons autre chose, WordPress s'arrête immédiatement et la demande d'origine ne sera pas envoyée.$r
est un tableau d'arguments pour cette demande. Nous devons aussi les changer en une minute.$url
est - surprise! - l'URL.Donc, dans notre rappel,
t5_update_wp_per_https()
nous regardons l'URL, et si c'est une URL que nous voulons filtrer, nous disons NON à WordPress en ne disant pas «non» (false
).Remarque: Il s'ensuit que vous pouvez empêcher toutes les requêtes HTTP avec:
add_filter( 'pre_http_request', '__return_true' );
Nous lançons notre propre demande à la place avec une meilleure URL et des arguments légèrement ajustés (
$r
, renommés pour plus$args
de lisibilité).Le code
Veuillez lire les commentaires en ligne, ils sont importants.
Les tests
Sans ce plugin WordPress utilisé:
http://api.wordpress.org/core/version-check/1.6/
pour les vérifications de mise à jour, ethttp://wordpress.org/wordpress-3.4.2.zip
pour télécharger les nouveaux fichiers.Je l' ai testé avec deux installations locales, un site unique et une configuration multi-site sur Win 7. Pour forcer une mise à jour ensemble I
$wp_version
danswp-includes/version.php
la1
et la version de TwentyEleven à1.3
.Pour surveiller le trafic réseau, j'ai utilisé Wireshark : c'est gratuit, il fonctionne sur Windows et Linux, et il propose des outils de filtrage impressionnants.
Regarder HTTPS est un peu difficile: vous voyez juste des données chiffrées… c'est l'idée après tout. Pour voir si mon plugin a fait ce qu'il devrait faire, j'ai d'abord regardé le trafic non crypté et noté l'adresse IP utilisée pour se connecter à wordpress.org. C'était
72.233.56.138
, parfois72.233.56.139
.Pas étonnant, il existe un équilibreur de charge et probablement de nombreux autres outils, nous ne pouvons donc pas compter sur une seule adresse IP.
Ensuite, j'ai tapé
ip.addr == 72.233.56.138
dans le masque de filtre, activé le plugin, suis allé voirwp-admin/update-core.php
le trafic dans Wireshark. Les lignes vertes sont des demandes en texte clair - exactement ce que nous ne voulons pas. Les lignes rouges et noires sont un signe de réussite.La vérification de la mise à jour s'est bien passée: elle a trouvé les versions «plus récentes». Les mises à jour réelles pour le thème et le noyau se sont également bien déroulées. Exactement ce dont j'avais besoin.
Et pourtant… cela pourrait être plus facile s'il y avait un simple filtre pour l'URL.
la source
/* /**/
, juste parce que c'est du génie. Et (si je pouvais) un autre +1 pour Charles Bronson. Et puis il devrait y avoir un autre +1 pour l'explication détaillée, les commentaires et les captures d'écran.la source