किसी भी HTTP अनुरोध URI को फ़िल्टर करें?


10

मैं HTTP API के माध्यम से किए गए किसी भी HTTP अनुरोध URI को फ़िल्टर करना चाहता हूं।

बक्सों का इस्तेमाल करें:

  1. वर्डप्रेस अपडेट चेक http://api.wordpress.org/core/version-check/1.6/ पर जाता है , लेकिन https://api.wordpress.org/core/version-check/1.6/ पर भी काम करता है, और मुझे चाहिए हमेशा इसका उपयोग करने के लिए।
  2. नई वर्डप्रेस फ़ाइल http://wordpress.org/wordpress-3.4.2.zip से ली गई है , लेकिन https://wordpress.org/wordpress-3.4.2.zip भी काम करती है।
  3. कभी-कभी मैं अनुरोधों को डीबग करना चाहता हूं और उन अस्थायी को अपने स्थानीय सर्वर पर एक कस्टम डोमेन पर पुनर्निर्देशित करना चाहता हूं।
  4. कुछ प्लगइन्स अन्य सर्वरों से अनुरोध करते हैं, और मैं बाहरी सर्वर के कम होने पर इन अनुरोधों को बदलना चाहता हूं।

अपडेट के अनुरोध अब के लिए सबसे महत्वपूर्ण हैं, क्योंकि अभी भी अधूरा बग 16778 ( अधिक जानकारी ) है, और HTTPS अनुरोध एक मैन-इन-द-मिडिल हमले के जोखिम को कम करते हैं।

मैंने अच्छी तरह से खोज की है , मैंने कोर कोड का अध्ययन किया है ... लेकिन दो साल पहले की तरह समाप्त हो गया है:

मुझे लगा कि आप HTTP अनुरोध के URL को फ़िल्टर कर सकते हैं, लेकिन अब मैं एक नहीं खोज सकता।

मुझसे क्या छूट गया? क्या मैंने? :)


WP में cURL डीबगिंग की खोज करने वाले किसी भी व्यक्ति के लिए इस उत्तर को यहां लिंक करना।
केसर

जवाबों:


9

एक उत्तर से कम, लेकिन इसके साथ मेरे अनुभव से सीधे चीजों की एक सूची - शायद आपने कुछ अनदेखी की है।

अनुरोध और उसके परिणामों को डीबग करना

Diggin के बिना अपडेट प्रक्रिया में बहुत गहरा है, लेकिन WP HTTP API WP_HTTPवर्ग का उपयोग करता है । यह एक अच्छी बात भी प्रस्तुत करता है: एक डिबग हुक।

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

जहां $responseएक WP_Errorवस्तु भी हो सकती है जो शायद आपको अधिक बताती है।

नोट: एक संक्षिप्त परीक्षण से, यह फ़िल्टर केवल (किसी कारण से) काम लगता है यदि आप इसे उस स्थान के करीब रखते हैं जहाँ आप वास्तव में अनुरोध कर रहे हैं। तो शायद आपको नीचे दिए गए किसी एक फ़िल्टर पर कॉलबैक के भीतर से कॉल करना होगा।

WP_HTTP वर्ग तर्क

कक्षाएं तर्क स्वयं फ़िल्टर करने योग्य होती हैं, लेकिन कुछ लोग WP के मानने की आवश्यकता वाले तरीकों से वापस प्राप्त करते हैं।

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

एक तर्क है ssl_verify, जो डिफ़ॉल्ट रूप से सच है (लेकिन मेरे लिए बड़े पैमाने पर समस्याओं का कारण बनता है - उदाहरण के लिए - गिटहब) से अपडेट करते समय। संपादित करें: परीक्षण अनुरोध को डीबग करने के बाद, मुझे एक और तर्क मिला कि सत्यापित करने के लिए सेट है कि क्या एसएसएल सेट है true। इसे कहा जाता है sslverify(अंडरस्कोर को अलग किए बिना)। कोई विचार नहीं है कि यह खेल में कहां आया, अगर यह वास्तव में उपयोग में है या छोड़ दिया गया है और यदि आपके पास इसके मूल्य को प्रभावित करने का मौका है। मैंने इसे 'http_api_debug'फिल्टर का उपयोग करके पाया ।

पूरी तरह से कस्टम

आप "बस" भी पूरे इंटर्नल को ओवरराइड कर सकते हैं और कस्टम सेटअप के साथ जा सकते हैं। उसके लिए एक फिल्टर है।

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

पहले आर्ग को सही पर सेट करने की आवश्यकता है। से आप अंदर के तर्कों $rऔर परिणाम से बातचीत कर सकते हैं parse_url( $url );

प्रतिनिधि

एक और चीज जो काम कर सकती है वह सब कुछ एक कस्टम प्रॉक्सी के माध्यम से चल सकती है। यह आपके में कुछ सेटिंग्स की जरूरत है wp-config.php। मैंने पहले कभी ऐसा करने की कोशिश नहीं की है, लेकिन मैं थोड़ी देर पहले स्थिरांक के माध्यम से भाग गया और कुछ उदाहरणों को अभिव्यक्त किया जो काम करना चाहिए और इसमें कुछ टिप्पणियां शामिल थीं जो मुझे एक दिन चाहिए। आप को परिभाषित करने के लिए है WP_PROXY_HOSTऔर WP_PROXY_PORTएक मिनट के रूप में। स्थापना। कुछ भी काम नहीं करेगा और यह बस आपके प्रॉक्सी को बायपास करेगा।

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

संपादित करें

WP_HTTPकक्षा सामान्य रूप से के रूप में कार्य आधार (विभिन्न परिदृश्यों के लिए बढ़ाया जाएगा) वर्ग। विस्तार WP_HTTP_*वर्ग हैं Fsockopen, Streams, Curl, Proxy, Cookie, Encoding। यदि आप 'http_api_debug'-बैक करने के लिए कॉलबैक को हुक करते हैं , तो तीसरा तर्क आपको बताएगा कि आपके अनुरोध के लिए किस वर्ग का उपयोग किया गया था।

WP_HTTP_curlकक्षा के अंदर , आपको request()विधि मिल जाएगी । यह विधि एसएसएल व्यवहार को रोकने के लिए दो फ़िल्टर प्रदान करती है: एक स्थानीय अनुरोधों के लिए 'https_local_ssl_verify'और एक दूरस्थ अनुरोधों के लिए 'https_ssl_verify'। WP संभवतः के localरूप में परिभाषित करेगा localhostऔर आपको इसके बदले में क्या मिलेगा get_option( 'siteurl' );

तो आपके द्वारा उस अनुरोध को करने से पहले (या एक कॉलबैक से जो निकटतम अनुरोध के लिए झुका हुआ है) करने के लिए मैं निम्नलिखित प्रयास करना चाहूंगा:

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

सिडेनोट: ज्यादातर मामलों में WP_HTTP_curlप्रॉक्सी को संभालने के लिए उपयोग किया जाएगा।


1
आह, मुझे लगता है कि आपने परोक्ष रूप से मेरे प्रश्न का उत्तर दिया है: मैं इसमें हुक कर सकता हूं pre_http_request, अनुरोध को रद्द कर सकता हूं और इसे सही URL के साथ फिर से भेज सकता हूं । आज रात की कोशिश करेंगे।
FUXIA

8

@ Kaiser के उपयोगी उत्तर के आधार पर मैंने कुछ कोड लिखे हैं जो अच्छी तरह से काम करते हैं। यही कारण है कि मैंने इसे उत्तर के रूप में चिह्नित किया है।

मुझे अपने समाधान की व्याख्या करें ...

तर्क

जब एक अनुरोध यह एपीआई के माध्यम से भेजा के माध्यम से चलाता है WP_Http::request()। यही तरीका है ...

@todo Refactor इस कोड को।

… इसके हेडर में। मैं और अधिक सहमत नहीं हो सका।

अब, कुछ फ़िल्टर हैं। मैंने pre_http_requestअपनी जरूरतों के लिए दुरुपयोग करने का फैसला किया :

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

हम तीन तर्कों यहाँ प्राप्त: false, $r, $url

  • falseके लिए अपेक्षित वापसी मूल्य है apply_filters()। यदि हम कुछ और वापस भेजते हैं, तो वर्डप्रेस तुरंत बंद हो जाता है, और मूल अनुरोध नहीं भेजा जाएगा।

  • $rउस अनुरोध के लिए तर्कों की एक सरणी है। हमें इन्हें एक मिनट में बदलना होगा।

  • $urlहै - आश्चर्य! - यूआरएल।

तो हमारे कॉलबैक में t5_update_wp_per_https()हम URL को देखते हैं, और अगर यह एक URL है जिसे हम फ़िल्टर करना चाहते हैं, तो हम NO को वर्डप्रेस को "नहीं" ( ) नहीं कह कर कहते हैं false

यहाँ छवि विवरण दर्ज करें

ध्यान दें: यह इस प्रकार है कि आप सभी HTTP अनुरोधों को रोक सकते हैं:
add_filter( 'pre_http_request', '__return_true' );

हम बेहतर URL और थोड़े समायोजित तर्कों ( $r, $argsपठनीयता के लिए पुनर्नामित ) के बजाय अपने स्वयं के अनुरोध को आग लगा देते हैं ।

कोड

कृपया इनलाइन टिप्पणियों को पढ़ें, वे महत्वपूर्ण हैं।

<?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;
}

जाँच

उस प्लगइन के बिना वर्डप्रेस का उपयोग किया गया:

  • http://api.wordpress.org/core/version-check/1.6/ अद्यतन जाँच के लिए, और
  • http://wordpress.org/wordpress-3.4.2.zip नई फ़ाइलों को डाउनलोड करने के लिए।

मैंने इसे दो स्थानीय प्रतिष्ठानों के साथ, एक एकल साइट और एक बहु-साइट सेटअप के साथ विन 7 पर परीक्षण किया। एक अपडेट जिसे मैं करने $wp_versionके wp-includes/version.phpलिए सेट करता हूं 1और ट्वेंटीलेवेन के संस्करण के लिए मजबूर करने के लिए 1.3

नेटवर्क ट्रैफ़िक देखने के लिए मैंने Wireshark का उपयोग किया : यह मुफ़्त है, यह विंडोज़ और लिनक्स पर चलता है, और यह कुछ प्रभावशाली फ़िल्टर टूल प्रदान करता है।

HTTPS देखना थोड़ा कठिन है: आप बस एन्क्रिप्टेड डेटा देखते हैं ... यही विचार है। यह देखने के लिए कि क्या मेरे प्लगइन ने यह किया है कि मुझे पहले अनएन्क्रिप्टेड ट्रैफ़िक को देखना चाहिए और wordpress.org से कनेक्ट करने के लिए उपयोग किए गए आईपी पते को नोट किया। वह था 72.233.56.138, कभी-कभी 72.233.56.139
आश्चर्य की बात नहीं, एक लोड बैलेंसर और शायद कई अन्य उपकरण हैं, इसलिए हम एक आईपी ​​पते पर भरोसा नहीं कर सकते हैं ।

फिर मैंने ip.addr == 72.233.56.138फिल्टर मास्क में टाइप किया, प्लगइन को सक्रिय किया, गया wp-admin/update-core.phpऔर विंडसरॉक में यातायात के लिए देखा। सादे पाठ में हरी रेखाएँ अनुरोध हैं - ठीक वही जो हम नहीं चाहते हैं। लाल और काली रेखाएं सफलता की निशानी हैं।

वायरशार्क

अपडेट की जाँच ठीक रही: इसमें "नए" संस्करण मिले। विषय और कोर के लिए वास्तविक अद्यतन भी ठीक चला। बिल्कुल वही जो मुझे चाहिए था।

और फिर भी ... यह आसान हो सकता है अगर यूआरएल के लिए एक साधारण फिल्टर था।


1
+1 के लिए /* /**/, सिर्फ इसलिए कि यह प्रतिभाशाली है। और (अगर मैं कर सकता था) चार्ल्स ब्रॉनसन के लिए एक और +1। और फिर विस्तृत विवरण, टिप्पणियों और स्क्रीनशॉट के लिए एक और +1 होना चाहिए।
कैसर

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
यह उल्लेख किया जाना चाहिए, कि इस कोड उदाहरण में, फ़ंक्शन http_api_curl_custom में, वैश्विक चर $ प्रतिस्थापित_url को उपयोग किए जाने के बाद NULL पर सेट किया जाना चाहिए। अन्यथा, url में "wordpress.org" की पहली घटना के बाद, अन्य सभी url को बदल दिया जाएगा।
मिहानइंतल्पो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.