HTTP 요청 URI를 필터링 하시겠습니까?


10

HTTP API를 통해 수행 된 모든 HTTP 요청 URI를 필터링하고 싶습니다.

사용 사례:

  1. WordPress 업데이트 확인은 http://api.wordpress.org/core/version-check/1.6/ 으로 이동하지만 https://api.wordpress.org/core/version-check/1.6/도 작동 하므로 원합니다. 이것을 항상 사용하십시오.
  2. 새 WordPress 파일은 http://wordpress.org/wordpress-3.4.2.zip 에서 가져 왔지만 https://wordpress.org/wordpress-3.4.2.zip도 작동합니다.
  3. 때로는 요청을 디버그하고 임시로 로컬 서버의 사용자 정의 도메인으로 리디렉션하려고합니다.
  4. 일부 플러그인은 다른 서버에 요청하기 때문에 외부 서버가 다운되면 이러한 요청을 교체하고 싶습니다.

아직 수정되지 않은 버그 16778 ( 자세한 정보 ) 이 있기 때문에 업데이트 요청이 가장 중요합니다. HTTPS 요청은 중간자 공격의 위험을 낮 춥니 다.

나는 철저히 검색했다 . 나는 핵심 코드를 연구했다. 그러나 2 년 전 Nacin처럼 끝났다.

HTTP 요청의 URL을 필터링 할 수 있다고 생각했지만 지금은 찾을 수 없습니다.

내가 놓친 게 무엇입니까? 내가 했어? :)


WP에서 cURL 디버깅을 검색하는 사람을 위해이 답변을 여기에 연결 하십시오.
kaiser

답변:


9

대답보다 적지 만 그것에 대한 나의 경험에서 나온 것의 목록 ​​일뿐입니다. 어쩌면 당신은 무언가를 간과했을 것입니다.

요청 및 결과 디버깅

업데이트 프로세스를 깊이 파고 들지 않으면 WP HTTP API가 WP_HTTP클래스를 사용합니다 . 또한 디버그 훅도 좋습니다.

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

어디 $response도 할 수있다 WP_Error어쩌면 더 알려줍니다 객체입니다.

참고 : 간단한 테스트에서이 필터 는 실제로 요청을 수행하는 위치에 가깝게 배치 한 경우에만 작동합니다 (어떤 이유로 든) . 따라서 아래 필터 중 하나의 콜백 내에서 호출해야 할 수도 있습니다.

WP_HTTP 클래스 인수

Classes 인수 자체는 필터링 가능하지만, 일부는 WP가 필요하다고 생각하는 것으로 내부 메소드에 의해 재설정됩니다.

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

인수 중 하나는 ssl_verify기본적으로 true입니다 (그러나 GitHub에서 업데이트 할 때 큰 문제가 발생합니다). 편집 : 테스트 요청을 디버깅 한 후 SSL이 설정되어 있는지 확인하도록 설정된 다른 인수를 찾았습니다 true. sslverify밑줄을 구분하지 않고 호출 합니다. 게임이 실제로 사용 중이거나 포기되고 그 가치에 영향을 줄 수있는 기회가 있는지 게임이 어디로 왔는지 전혀 알 수 없습니다. 'http_api_debug'필터를 사용하여 찾았습니다 .

완전 맞춤형

또한 전체 내부를 "간단하게"재정의하고 사용자 지정 설정을 수행 할 수도 있습니다. 이를위한 필터가 있습니다.

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

첫 번째 인수는 true로 설정해야합니다. 내부의 인수 $r및의 결과와 상호 작용할 수있는 것보다 parse_url( $url );.

대리

작동하는 또 다른 것은 사용자 정의 프록시를 통해 모든 것을 실행할 수 있습니다. 에 일부 설정이 필요합니다 wp-config.php. 나는 이것을 전에 시도한 적이 없지만 상수를 잠시 동안 실행하고 언젠가 필요할 경우 작동 해야 하고 주석을 포함 해야하는 몇 가지 예를 요약했습니다 . 당신은 정의해야 WP_PROXY_HOST하고 WP_PROXY_PORTA 최소로. 환경. 그렇지 않으면 아무것도 작동하지 않으며 단순히 프록시를 우회합니다.

# 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'-action에 연결하면 세 번째 인수가 요청에 사용 된 클래스를 알려줍니다.

WP_HTTP_curl클래스 안에는 request()메소드가 있습니다. 이 방법은 SSL 동작을 가로 채기위한 두 가지 필터를 제공합니다. 하나는 로컬 요청 용 '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의 유용한 답변을 바탕으로 잘 작동하는 것으로 보이는 코드를 작성했습니다. 그것이 내가 답변으로 표시 한 이유입니다.

내 해결책을 설명하겠습니다 ...

논리

요청이 API를 통해 전송되면를 통해 실행됩니다 WP_Http::request(). 그 방법은 ...

@todo이 코드를 리팩터링하십시오.

… 헤더에. 더 동의 할 수 없었습니다.

이제 몇 가지 필터가 있습니다. 나는 pre_http_request내 필요 에 오용하기로 결정했다 .

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

여기에는 세 가지 주장이 있습니다 false, $r, $url.

  • false의 예상 반환 값입니다 apply_filters(). 다른 것을 다시 보내면 WordPress가 즉시 중지되고 원래 요청이 전송되지 않습니다.

  • $r해당 요청에 대한 인수 배열입니다. 우리도 이것들을 1 분 안에 바꿔야합니다.

  • $url– 놀랍습니다! – URL.

따라서 콜백 t5_update_wp_per_https()에서 URL을보고 URL 인 경우 필터링하려는 경우 "no"( ) 라고 말하지 않고 WordPress에 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;
}

테스트

해당 플러그인이 없으면 WordPress가 사용됩니다.

  • http://api.wordpress.org/core/version-check/1.6/ 업데이트 확인 및
  • http://wordpress.org/wordpress-3.4.2.zip 새 파일을 다운로드하십시오.

나는 두 개의 로컬 설치, 단일 사이트 및 업데이트 I 세트를 강제로 윈 7에 멀티 사이트 설치와 테스트 $wp_versionwp-includes/version.php1와에 TwentyEleven의 버전 1.3.

내가 사용한 Wireshark 의 네트워크 트래픽을 보려면 : 무료이며 Windows 및 Linux에서 실행되며 인상적인 필터 도구를 제공합니다.

HTTPS를 보는 것은 조금 어렵습니다. 암호화 된 데이터 만 볼 수 있습니다. 결국 아이디어입니다. 플러그인이 어떻게해야하는지 확인하기 위해 먼저 암호화되지 않은 트래픽을보고 wordpress.org에 연결하는 데 사용 된 IP 주소를 기록했습니다. 즉이었다 72.233.56.138때때로 72.233.56.139.
당연히,로드 밸런서 및 기타 많은 도구가 있으므로 하나의 IP 주소 에 의존 할 수 없습니다 .

그런 다음 ip.addr == 72.233.56.138필터 마스크를 입력 하고 플러그인을 활성화 한 다음 wp-admin/update-core.phpWireshark의 트래픽을 확인했습니다. 초록색 선은 원치 않는 요청입니다. 정확히 우리가 원하지 않는 것입니다. 빨간색과 검은 색 선은 성공의 표시입니다.

와이어 샤크

업데이트 확인이 잘되었습니다.“최신”버전을 찾았습니다. 테마와 핵심에 대한 실제 업데이트도 훌륭했습니다. 정확히 내가 필요한 것.

그리고 여전히 ... URL에 대한 간단한 필터가 있으면 더 쉬울 수 있습니다.


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에서 전역 변수 $ replaced_url은 사용 된 후 NULL로 설정되어야합니다. 그렇지 않으면, URL에서 "wordpress.org"가 처음 발생한 후에 다른 모든 URL이 대체됩니다.
MihanEntalpo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.