Ich möchte jeden HTTP-Anforderungs-URI filtern, der über die HTTP-API ausgeführt wird.
Anwendungsfälle:
- Die Überprüfung des WordPress-Updates erfolgt unter http://api.wordpress.org/core/version-check/1.6/ , aber https://api.wordpress.org/core/version-check/1.6/ funktioniert auch, und ich möchte dies immer zu benutzen.
- Die neue WordPress-Datei stammt von http://wordpress.org/wordpress-3.4.2.zip , aber https://wordpress.org/wordpress-3.4.2.zip funktioniert auch.
- Manchmal möchte ich Anforderungen debuggen und diese temporär an eine benutzerdefinierte Domäne auf meinem lokalen Server umleiten.
- Einige Plugins stellen Anforderungen an andere Server, und ich möchte diese Anforderungen ersetzen, wenn der externe Server ausfällt.
Die Aktualisierungsanforderungen sind vorerst die wichtigsten, da der Fehler 16778 ( weitere Informationen ) immer noch nicht behoben ist und HTTPS-Anforderungen das Risiko eines Man-in-the-Middle-Angriffs verringern .
Ich habe gründlich gesucht , den Kerncode studiert… aber vor zwei Jahren wie Nacin gelandet:
Ich war mir sicher, dass Sie die URL einer HTTP-Anfrage filtern können, aber jetzt kann ich keine finden.
Was habe ich verpasst? Habe ich? :) :)
Antworten:
Weniger als eine Antwort, aber nur eine Liste von Dingen, die direkt aus meiner Erfahrung damit stammen - vielleicht haben Sie etwas übersehen.
Debuggen der Anfrage und ihrer Ergebnisse
Ohne zu tief in den Aktualisierungsprozess einzudringen, aber die WP HTTP API verwendet die
WP_HTTP
Klasse. Es bietet auch eine schöne Sache: Ein Debug-Hook.Wo
$response
kann auch einWP_Error
Objekt sein, das Ihnen vielleicht mehr sagt.Hinweis: Nach einem kurzen Test scheint dieser Filter (aus irgendeinem Grund) nur zu funktionieren, wenn Sie ihn so nahe an der Stelle platzieren, an der Sie die Anforderung tatsächlich ausführen. Vielleicht müssen Sie es innerhalb eines Rückrufs auf einem der folgenden Filter aufrufen.
WP_HTTP
KlassenargumenteDie Classes-Argumente selbst sind filterbar, aber einige werden von den internen Methoden der Methoden auf das zurückgesetzt, was WP für erforderlich hält.
Eines der Argumente ist
ssl_verify
, dass dies standardmäßig zutrifft (aber für mich verursacht es massive Probleme beim Aktualisieren von beispielsweise GitHub). Bearbeiten: Nach dem Debuggen einer Testanforderung habe ich ein anderes Argument gefunden, mit dem überprüft werden soll, ob SSL aktiviert isttrue
. Es heißtsslverify
(ohne Unterstrich). Keine Ahnung, wo dies ins Spiel kam, ob es tatsächlich benutzt oder aufgegeben wird und ob Sie die Chance haben, seinen Wert zu beeinflussen. Ich habe es mit dem'http_api_debug'
Filter gefunden.Völlig individuell
Sie können auch "einfach" die gesamten Interna überschreiben und ein benutzerdefiniertes Setup durchführen. Dafür gibt es einen Filter.
Das erste Argument muss auf true gesetzt werden. Dann können Sie mit den Argumenten im Inneren
$r
und dem Ergebnis von interagierenparse_url( $url );
.Proxy
Eine andere Sache, die funktionieren könnte, könnte sein, alles über einen benutzerdefinierten Proxy auszuführen. Dies erfordert einige Einstellungen in Ihrem
wp-config.php
. Ich habe das noch nie versucht, aber ich habe vor einiger Zeit die Konstanten durchgearbeitet und einige Beispiele zusammengefasst, die funktionieren sollten , und einige Kommentare hinzugefügt, falls ich sie eines Tages brauche. Sie müssen definierenWP_PROXY_HOST
undWP_PROXY_PORT
als min. Rahmen. Sonst funktioniert nichts und es wird einfach Ihr Proxy umgangen.BEARBEITEN
Die
WP_HTTP
Klasse fungiert normalerweise als Basisklasse (wird für verschiedene Szenarien erweitert). Die VerlängerungsWP_HTTP_*
Klassen sindFsockopen
,Streams
,Curl
,Proxy
,Cookie
,Encoding
. Wenn Sie einen Rückruf an die'http_api_debug'
-action verknüpfen, gibt das dritte Argument an, welche Klasse für Ihre Anforderung verwendet wurde.In der
WP_HTTP_curl
Klasse finden Sie dierequest()
Methode. Diese Methode bietet zwei Filter zum Abfangen des SSL-Verhaltens: einen für lokale Anforderungen'https_local_ssl_verify'
und einen für Remote-Anforderungen'https_ssl_verify'
. WP wird wahrscheinlich definieren,local
alslocalhost
und was Sie als Gegenleistung erhaltenget_option( 'siteurl' );
.Ich würde also Folgendes versuchen, bevor Sie diese Anforderung ausführen (oder von einem Rückruf, der mit der nächstgelegenen Anforderung verknüpft ist:
Nebenbemerkung: In den meisten Fällen
WP_HTTP_curl
werden Proxies verwendet.quelle
pre_http_request
einbinden, die Anfrage abbrechen und sie mit der richtigen URL erneut senden. Werde das heute Abend versuchen.Basierend auf der nützlichen Antwort von @ kaiser habe ich einen Code geschrieben, der gut zu funktionieren scheint. Das ist der Grund, warum ich es als Die Antwort markiert habe.
Lassen Sie mich meine Lösung erklären ...
Die Logik
Wenn eine über die API gesendete Anforderung ausgeführt wird
WP_Http::request()
. Das ist die Methode mit…… In seiner Kopfzeile. Ich konnte nicht mehr zustimmen.
Nun gibt es einige Filter. Ich habe beschlossen,
pre_http_request
für meine Bedürfnisse zu missbrauchen :Wir bekommen hier drei Argumente :
false, $r, $url
.false
ist der erwartete Rückgabewert fürapply_filters()
. Wenn wir etwas anderes zurückschicken, stoppt WordPress sofort und die ursprüngliche Anfrage wird nicht gesendet.$r
ist ein Array von Argumenten für diese Anforderung. Auch diese müssen wir in einer Minute ändern.$url
ist - Überraschung! - die URL.In unserem Rückruf sehen
t5_update_wp_per_https()
wir uns also die URL an. Wenn es sich um eine URL handelt, die wir filtern möchten, sagen wir NEIN zu WordPress, indem wir nicht "Nein" sagen (false
).Randnotiz: Folglich können Sie alle HTTP-Anforderungen verhindern mit:
add_filter( 'pre_http_request', '__return_true' );
Wir feuern unseren eigenen Wunsch statt mit einer besseren URL und angepasst Argumenten leicht (
$r
umbenannt , um$args
Lesbarkeit zu verbessern).Der Code
Bitte lesen Sie die Inline-Kommentare, sie sind wichtig.
Die Tests
Ohne dieses Plugin verwendet WordPress:
http://api.wordpress.org/core/version-check/1.6/
für Update-Prüfungen undhttp://wordpress.org/wordpress-3.4.2.zip
um die neuen Dateien herunterzuladen.Getestet habe ich es mit zwei lokalen Installationen, einer einzigen Seite einer Multi-Site - Setup auf Win 7. Um ein Update I Satz zu erzwingen
$wp_version
inwp-includes/version.php
zu1
und die Version von TwentyEleven zu1.3
.Um den Netzwerkverkehr zu beobachten, habe ich Wireshark verwendet : Es ist kostenlos, läuft unter Windows und Linux und bietet einige beeindruckende Filter-Tools.
Das Anschauen von HTTPS ist etwas schwierig: Sie sehen nur verschlüsselte Daten… das ist schließlich die Idee. Um zu sehen, ob mein Plugin das getan hat, was es tun sollte, habe ich zuerst den unverschlüsselten Verkehr beobachtet und die IP-Adresse notiert, die für die Verbindung zu wordpress.org verwendet wurde. Das war
72.233.56.138
manchmal so72.233.56.139
.Kein Wunder, dass es einen Load Balancer und wahrscheinlich viele andere Tools gibt, sodass wir uns nicht auf eine IP-Adresse verlassen können.
Dann tippte ich
ip.addr == 72.233.56.138
in die Filtermaske, aktivierte das Plugin, ging zuwp-admin/update-core.php
und beobachtete den Verkehr in Wireshark. Grüne Linien sind Anfragen im Klartext - genau das, was wir nicht wollen. Die roten und schwarzen Linien sind ein Zeichen des Erfolgs.Die Update-Prüfung verlief einwandfrei: Es wurden die "neueren" Versionen gefunden. Die eigentlichen Updates für das Thema und den Kern gingen auch gut. Genau das, was ich brauchte.
Und trotzdem… das könnte einfacher sein, wenn es einen einfachen Filter für die URL gäbe.
quelle
/* /**/
, nur weil es genial ist. Und (wenn ich könnte) noch +1 für Charles Bronson. Und dann sollte es noch eine +1 für die detaillierten Erklärungen, Kommentare und Screenshots geben.quelle