Herhangi bir HTTP isteği URI'sine filtre uygulanıyor mu?


10

HTTP API üzerinden yapılan herhangi bir HTTP isteği URI'sini filtrelemek istiyorum.

Kullanım örnekleri:

  1. WordPress güncelleme kontrolü http://api.wordpress.org/core/version-check/1.6/ adresine gider , ancak https://api.wordpress.org/core/version-check/1.6/ de çalışır ve istiyorum bunu her zaman kullanmak için.
  2. Yeni WordPress dosyası http://wordpress.org/wordpress-3.4.2.zip adresinden alınır , ancak https://wordpress.org/wordpress-3.4.2.zip de çalışır.
  3. Bazen isteklerde hata ayıklamak ve geçici olanları yerel sunucumdaki özel bir etki alanına yönlendirmek istiyorum.
  4. Bazı eklentiler diğer sunuculara istekte bulunur ve harici sunucu çöktüğünde bu istekleri değiştirmek istiyorum.

Güncelleme istekleri şimdilik en önemlisidir, çünkü hala düzeltilmemiş hata 16778 ( daha fazla bilgi ) vardır ve HTTPS istekleri ortadaki bir Adam saldırısı riskini azaltır.

Ben var arandı iyice ben çekirdek kodunu inceledik ... ama iki yıl önce Nacin gibi sona erdi:

Bir HTTP isteğinin URL'sini filtreleyebileceğinizden eminim, ancak şimdi bir tane bulamıyorum.

Ne kaçırdım? Öyle mi? :)


Bu cevabı , WP'de cURL hata ayıklaması arayan herkes için buraya bağlamak .
kaiser

Yanıtlar:


9

Bir cevaptan daha az, ama sadece onunla olan deneyimimden sadece bir şeyler listesi - belki bir şeyleri gözden kaçırdınız.

İstek ve sonuçlarında hata ayıklama

Diggin olmadan güncelleme süreci çok derin, ama WP HTTP API WP_HTTPsınıfı kullanır . Ayrıca güzel bir şey sunar: Hata ayıklama kancası.

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

Nerede size daha fazlasını anlatan $responsebir WP_Errornesne de olabilir .

Not: Kısa bir testten sonra, bu filtre yalnızca (bazı nedenlerden dolayı) isteği gerçekte yaptığınız yere yakın yerleştirirseniz çalışır . Bu nedenle, aşağıdaki filtrelerden birindeki geri arama ile aramanız gerekebilir.

WP_HTTP Sınıf argümanları

Sınıflar argümanlarının kendisi filtrelenebilir, ancak afaik bazıları WP'nin gerekli olduğunu varsaydığı yöntemlere geri döner.

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

Bağımsız değişkenlerden biri ssl_verify, varsayılan olarak doğrudur (ancak benim için - örneğin - GitHub'dan güncelleme yaparken büyük sorunlara neden olur). Düzenleme: Bir test isteğinde hata ayıkladıktan sonra, SSL'nin ayarlanmış olup olmadığını doğrulamak için ayarlanmış başka bir bağımsız değişken buldum true. Denir sslverify(alt çizgi ayırmadan). Oyunun nereden geldiğine dair bir fikrim yok, eğer gerçekten kullanımda veya terkedilmişse ve değerini etkileme şansınız varsa. 'http_api_debug'Filtreyi kullanarak buldum .

Tamamen özel

Ayrıca tüm iç kısımları "basitçe" geçersiz kılabilir ve özel bir kurulumla devam edebilirsiniz. Bunun için bir filtre var.

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

İlk arg öğesinin true değerine ayarlanması gerekir. Daha sonra içerideki argümanlar $rve sonucu ile etkileşime girebilirsiniz parse_url( $url );.

vekil

Çalışabilecek başka bir şey, her şeyi özel bir Proxy üzerinden çalıştırmak olabilir. Bunun için bazı ayarların yapılması gerekiyor wp-config.php. Bunu daha önce hiç denemedim, ancak sabitleri bir süre önce koştum ve çalışması gereken bazı örnekleri özetledim ve bir gün ihtiyacım olması durumunda bazı yorumları da ekledim. Sen tanımlamak zorunda WP_PROXY_HOSTve WP_PROXY_PORTbir dakika kadar. ayarı. Başka hiçbir şey işe yaramaz ve sadece proxy'nizi atlar.

# 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' );

DÜZENLE

WP_HTTPSınıf normal olarak hareket baz (farklı senaryolar için uzatılır) sınıfı. Uzanan WP_HTTP_*sınıfları Fsockopen, Streams, Curl, Proxy, Cookie, Encoding. 'http_api_debug'-Action işlevine bir geri çağırma bağlarsanız, üçüncü argüman isteğiniz için hangi sınıfın kullanıldığını size bildirir.

İçinde WP_HTTP_curlClass, bulacağınız request()yöntemi. Bu yöntem, SSL davranışını durdurmak için iki filtre sunar: Biri yerel istekler için 'https_local_ssl_verify've diğeri uzak istekler için 'https_ssl_verify'. WP muhtemelen localolarak localhostve karşılığında ne alacağınızı tanımlayacaktır get_option( 'siteurl' );.

Yani, bu isteği yapmadan önce (ya da en yakın talebe bağlı olan bir geri çağrıdan) aşağıdakileri denemek istiyorum:

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' );

Sidenote: Çoğu durumda WP_HTTP_curlProxy'leri işlemek için kullanılır.


1
Ah, sanırım sorumu dolaylı olarak cevapladınız: pre_http_requestİstekte bulunabilir, isteği iptal edebilir ve doğru URL ile tekrar gönderebilirim. Bunu bu gece deneyeceğim.
fuxia

8

@ Kaiser yararlı cevap dayanarak ben iyi çalışıyor gibi görünüyor bazı kod yazdık. Cevap olarak işaretlememin nedeni budur.

Çözümümü açıklayayım…

Mantık

API üzerinden gönderilen bir istek gerçekleştiğinde WP_Http::request(). Bu yöntem ...

@todo Bu kodu yeniden düzenleyin.

... başlığında. Daha fazla anlaşamadım.

Şimdi bazı filtreler var. pre_http_requestİhtiyaçlarımı kötüye kullanmaya karar verdim :

add_filter( 'pre_http_request', 't5_update_wp_per_https', 10, 3 );

Biz burada üç bağımsız değişken olsun: false, $r, $url.

  • falseiçin beklenen getiri değeridir apply_filters(). Başka bir şey geri gönderirsek, WordPress hemen durur ve orijinal istek gönderilmez.

  • $r, bu istek için bir argüman dizisidir. Bunları bir dakika içinde de değiştirmeliyiz.

  • $url- sürpriz! - URL.

Yani bizim geri aramasında t5_update_wp_per_https()biz URL'ye bakın ve biz filtreye istediğiniz bir URL ise, söylediğimiz HAYIR tarafından WordPress değil ( “hayır” diyerek false).

resim açıklamasını buraya girin

Yan not: Aşağıdaki tüm HTTP isteklerini aşağıdakilerle engelleyebilirsiniz:
add_filter( 'pre_http_request', '__return_true' );

Bunun yerine kendi isteğimizi daha iyi bir URL ve biraz düzeltilmiş argümanlar ( okunabilirlik olarak $ryeniden adlandırıldı $args) ile tetikliyoruz.

Kod

Lütfen satır içi yorumları okuyun, bunlar önemlidir.

<?php
/**
 * Plugin Name: T5 Update WP per HTTPS
 * Description: Forces update checks and downloads for WP to use HTTPS.
 * Plugin URI:  http://wordpress.stackexchange.com/questions/72529/filter-any-http-request-uri
 * Version:     2012.11.14
 * Author:      Thomas Scholz
 * Author URI:  http://toscho.de
 * Licence:     MIT
 * License URI: http://opensource.org/licenses/MIT
 */

add_filter( 'pre_http_request', 't5_update_wp_per_https', 10, 3 );

/**
 * Force HTTPS requests for update checks and new WP version downloads.
 *
 * @wp-hook pre_http_request
 * @param   bool   $false
 * @param   array  $args
 * @param   string $url
 * @return  FALSE|array|object FALSE if everything is okay, an array of request
 *                            results or an WP_Error instance.
 */
function t5_update_wp_per_https( $false, $args, $url )
{
    // Split the URL into useful parts.
    $url_data = parse_url( $url );

    // It is already HTTPS.
    if ( 'https' === strtolower( $url_data['scheme'] ) )
        return FALSE;

    // Not our host.
    if ( FALSE === stripos( $url_data['host'], 'wordpress.org' ) )
        return FALSE;

    // Make that an HTTPS request.
    $new_url = substr_replace( $url, 'https', 0, 4 );

    // WP_Http cannot verify the wordpress.org certificate.
    $args['sslverify'] = FALSE;

    // It is slow. We wait at least 30 seconds.
    30 > $args['timeout'] and $args['timeout'] = 30;

    // Get an instance of WP_Http.
    $http    = _wp_http_get_object();

    // Get the result.
    $result = $http->request( $new_url, $args );

    /* prepend this line with a '#' to debug like a boss.
    print '<pre>'
    . htmlspecialchars( print_r( $result, TRUE ), ENT_QUOTES, 'utf-8', FALSE )
    . '</pre>';
    die();
    /**/

    return $result;
}

Testler

Bu eklenti olmadan WordPress kullanılmadı:

  • http://api.wordpress.org/core/version-check/1.6/ güncelleme kontrolleri için ve
  • http://wordpress.org/wordpress-3.4.2.zip yeni dosyaları indirmek için.

Ben iki yerel tesisler, tek bir site ve bir güncelleme ben setini zorlamak için Win 7. bir çok site kurulumu ile test $wp_versioniçinde wp-includes/version.phpiçin 1ve TwentyEleven sürümüne 1.3.

Wireshark kullandığım ağ trafiğini izlemek için : Ücretsizdir, Windows ve Linux üzerinde çalışır ve bazı etkileyici filtre araçları sunar.

HTTPS izlemek biraz zor: Sadece şifrelenmiş veri görüyorsunuz… sonuçta fikir bu. Eklentimin yapması gerekeni yapıp yapmadığını görmek için önce şifrelenmemiş trafiği izledim ve wordpress.org'a bağlanmak için kullanılan IP adresini not ettim. 72.233.56.138Bazen de öyleydi 72.233.56.139.
Şaşırtıcı olmayan bir şekilde, bir yük dengeleyici ve muhtemelen birçok araç var, bu yüzden bir IP adresine güvenemeyiz .

Sonra ip.addr == 72.233.56.138filtre maskesine girdim, eklentiyi etkinleştirdim, wp-admin/update-core.phpWireshark'taki trafiği izledim ve izledim. Yeşil çizgiler, düz metin biçiminde isteklerdir - tam olarak istemediğimiz şey. Kırmızı ve siyah çizgiler başarının bir işaretidir.

Wireshark

Güncelleme kontrolü iyi gitti: “Daha yeni” sürümleri buldu. Tema ve çekirdek için gerçek güncellemeler de iyi gitti. Tam olarak ihtiyacım olan şey.

Yine de… URL için basit bir filtre olsaydı bu daha kolay olabilirdi.


1
+1 /* /**/, çünkü dahice. Ve eğer yapabilirsem Charles Bronson için bir +1 daha. Ve sonra ayrıntılı açıklama, yorumlar ve ekran görüntüleri için başka bir +1 olmalıdır.
Kaiser

3
    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
Bu kod örneğinde, http_api_curl_custom işlevinde, $ replace_url genel değişkeninin kullanıldıktan sonra NULL olarak ayarlanması gerektiği belirtilmelidir. Aksi takdirde, url'de "wordpress.org" un ilk ortaya çıkmasından sonra diğer tüm URL'ler değiştirilir.
MihanEntalpo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.