wake-up-neo.net

HTTP-Anforderungs-URI filtern?

Ich möchte jeden HTTP-Anforderungs-URI filtern, der über die HTTP-API erfolgt.

Anwendungsfälle:

  1. Der WordPress-Update-Check 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 das immer benutzen.
  2. Die neue WordPress-Datei stammt aus http://wordpress.org/wordpress-3.4.2.Zip , aber https://wordpress.org/wordpress-3.4.2.Zip funktioniert auch.
  3. Manchmal möchte ich Anfragen debuggen und diese temporär an eine benutzerdefinierte Domäne auf meinem lokalen Server umleiten.
  4. Einige Plugins stellen Anfragen an andere Server, und ich möchte diese Anfragen ersetzen, wenn der externe Server ausfällt.

Die Aktualisierungsanforderungen sind für den Moment die wichtigsten, da der Fehler 16778 ( weitere Informationen ) noch nicht behoben ist und HTTPS-Anforderungen das Risiko eines Man-in-the-Middle-Angriffs verringern.

Ich habe gesuchtgründlich , ich habe den Kerncode studiert… aber bin vor zwei Jahren wie Nacin gelandet:

Ich dachte, Sie könnten die URL einer HTTP-Anfrage filtern, aber jetzt kann ich keine finden.

Was habe ich verpasst? Habe ich? :)

9
fuxia

Weniger als eine Antwort, sondern nur eine Liste von Dingen, die ich aus Erfahrung damit gemacht habe - vielleicht haben Sie etwas übersehen.

Debuggen der Anfrage und ihrer Ergebnisse

Ohne zu tief in den Aktualisierungsprozess einzugreifen, aber die HTTP-API WP verwendet die Klasse WP_HTTP. Es bietet auch eine nette Sache: Ein Debug-Hook.

do_action( 'http_api_debug', $response, 'response', $class, $args, $url );

Wobei $response auch ein WP_Error-Objekt sein kann, das Ihnen vielleicht mehr sagt.

Hinweis: Nach einem kurzen Test scheint dieser Filter nur (aus irgendeinem Grund) zu funktionieren, wenn Sie ihn als nah an der Stelle platzieren, an der Sie die Anforderung tatsächlich ausführen. Vielleicht müssen Sie es also innerhalb eines Rückrufs über einen der folgenden Filter aufrufen.

WP_HTTP Klassenargumente

Die Argumente von Classes selbst können gefiltert werden, aber einige werden von den internen Methoden auf das zurückgesetzt, was WP für erforderlich hält.

apply_filters( 'http_request_args', $r, $url );

Eines der Argumente ist ssl_verify, was standardmäßig zutrifft (aber für mich verursacht es massive Probleme beim Aktualisieren von - zum Beispiel - GitHub). Bearbeiten: Nach dem Debuggen einer Testanforderung habe ich ein anderes Argument gefunden, das festgelegt ist, um zu überprüfen, ob SSL auf true festgelegt ist. Es heißt sslverify (ohne Unterstrich). Keine Ahnung, wo dies ins Spiel gekommen ist, ob es tatsächlich verwendet 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 benutzerdefiniert

Sie können auch "einfach" die gesamten Interna überschreiben und ein benutzerdefiniertes Setup vornehmen. Dafür gibt es einen Filter.

apply_filters( 'pre_http_request', false, $r, $url );

Das erste Argument muss auf true gesetzt werden. Dann können Sie mit den Argumenten in $r und dem Ergebnis von parse_url( $url ); interagieren.

Proxy

Möglicherweise funktioniert auch alles über einen benutzerdefinierten Proxy. 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 WP_PROXY_Host und WP_PROXY_PORT als min definieren. Rahmen. Andernfalls funktioniert nichts und der Proxy wird einfach umgangen.

# HTTP Proxies
# Used for e.g. in Intranets
# Fixes Feeds as well
# Defines the proxy adresse.
define( 'WP_PROXY_Host',          '127.0.84.1' );
# Defines the proxy port.
define( 'WP_PROXY_PORT',          '8080' );
# Defines the proxy username.
define( 'WP_PROXY_USERNAME',      'my_user_name' );
# Defines the proxy password.
define( 'WP_PROXY_PASSWORD',      'my_password' );
# Allows you to define some adresses which
# shouldn't be passed through a proxy.
define( 'WP_PROXY_BYPASS_HOSTS',  'localhost, www.example.com' );

BEARBEITEN

Die Klasse WP_HTTP fungiert normalerweise als base class (wird für verschiedene Szenarien erweitert). Die Erweiterungsklassen für WP_HTTP_* sind Fsockopen, Streams, Curl, Proxy, Cookie, Encoding. Wenn Sie einen Rückruf mit der Aktion 'http_api_debug'- einbinden, wird im dritten Argument angegeben, welche Klasse für Ihre Anforderung verwendet wurde.

In der Klasse WP_HTTP_curl finden Sie die Methode request(). Diese Methode bietet zwei Filter zum Abfangen des SSL-Verhaltens: einen für lokale Anforderungen 'https_local_ssl_verify' und einen für Remoteanforderungen 'https_ssl_verify'. WP definiert wahrscheinlich local als localhost und was Sie als Gegenleistung für get_option( 'siteurl' ); erhalten.

Ich würde also Folgendes versuchen, bevor Sie diese Anforderung ausführen (oder von einem Rückruf aus, der mit der nächsten Anforderung verknüpft ist:

add_filter( 'https_ssl_verify', '__return_true' );

# Local requests should be checked with something like
# 'localhost' === $_SERVER['HTTP_Host'] or similar
# add_filter( 'https_local_ssl_verify', '__return_true' );

Hinweis: In den meisten Fällen wird WP_HTTP_curl verwendet, um mit Proxies umzugehen.

8
kaiser
    add_filter('http_request_args', 'http_request_args_custom', 10,2);
    function http_request_args_custom($request,$url){
            if (strpos($url, 'wordpress.org') !== false){
                    global $replaced_url;
                    $replaced_url = 'http://wordpress.local';
            }
            return $request;
    }

    add_action('http_api_curl', 'http_api_curl_custom');
    function http_api_curl_custom(&$handle){
            global $replaced_url;
            if (!is_null($replaced_url))
                    curl_setopt( $handle, CURLOPT_URL, $replaced_url);
    }

    $http = new WP_Http();
    $response = $http->request('http://wordpress.org', array());

    var_dump($response);
1
Butuzov