Plugin Directory

Changeset 2953445


Ignore:
Timestamp:
08/14/2023 05:09:43 PM (3 years ago)
Author:
unbouncewordpress
Message:

Releasing version 1.1.0

Location:
unbounce
Files:
16 edited
1 copied

Legend:

Unmodified
Added
Removed
  • unbounce/tags/1.1.0/UBConfig.php

    r2823212 r2953445  
    66    const UB_PLUGIN_NAME           = 'ub-wordpress';
    77    const UB_CACHE_TIMEOUT_ENV_KEY = 'UB_WP_ROUTES_CACHE_EXP';
    8     const UB_USER_AGENT            = 'Unbounce WP Plugin 1.0.49';
    9     const UB_VERSION               = '1.0.49';
     8    const UB_USER_AGENT            = 'Unbounce WP Plugin 1.1.0';
     9    const UB_VERSION               = '1.1.0';
    1010
    1111    // WP Admin Pages
     
    7373    {
    7474        $domain = getenv('UB_PAGE_SERVER_DOMAIN');
    75         return $domain ? $domain : 'wp.unbounce.com';
     75        return $domain ? $domain : 'proxy.unbouncepages.com';
    7676    }
    7777
     
    189189            $curl = curl_init();
    190190            $curl_options = array(
    191             CURLOPT_URL => $url,
    192             CURLOPT_CUSTOMREQUEST => "GET",
    193             CURLOPT_HEADER => true,
    194             CURLOPT_USERAGENT => UBConfig::UB_USER_AGENT,
    195             CURLOPT_HTTPHEADER => array('Host: ' . $domain, 'If-None-Match: ' . $etag),
    196             CURLOPT_RETURNTRANSFER => true,
    197             CURLOPT_FOLLOWLOCATION => false,
    198             CURLOPT_TIMEOUT => 5
     191                CURLOPT_URL => $url,
     192                CURLOPT_CUSTOMREQUEST => "GET",
     193                CURLOPT_HEADER => true,
     194                CURLOPT_USERAGENT => UBConfig::UB_USER_AGENT,
     195                CURLOPT_HTTPHEADER => UBHTTP::convert_headers_to_curl(
     196                    array(
     197                        'x-forwarded-host' => $domain,
     198                        'if-none-match' => $etag
     199                    )
     200                ),
     201                CURLOPT_RETURNTRANSFER => true,
     202                CURLOPT_FOLLOWLOCATION => false,
     203                CURLOPT_TIMEOUT => 5
    199204            );
    200205
  • unbounce/tags/1.1.0/UBDiagnostics.php

    r2823212 r2953445  
    3535                '>='
    3636            ),
    37             'SNI Support' => self::hasSNI(),
    38         );
    39     }
    40 
    41     public static function hasSNI()
     37            'SNI Support' => self::has_sni(),
     38        );
     39    }
     40
     41    public static function has_sni()
    4242    {
    4343        return defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME;
     
    101101        'PHP Version'             => phpversion(),
    102102        'WordPress Version'       => UBDiagnostics::wordpress_version(),
    103         'Unbounce Plugin Version' => '1.0.49',
     103        'Unbounce Plugin Version' => '1.1.0',
    104104        'Checks'                  => self::pp(UBDiagnostics::checks($domain, $domain_info)),
    105105        'Options'                 => self::pp(UBDiagnostics::ub_options()),
     
    111111        'Plugin Details'          => self::pp(get_plugins()),
    112112        'Curl Version'            => self::pp(UBDiagnostics::curl_version()),
    113         'SNI Support'             => self::hasSNI(),
     113        'SNI Support'             => self::has_sni(),
    114114        'Configuration Options'   => self::pp(self::phpConfig()),
    115115        'Extensions'              => self::pp(get_loaded_extensions()),
     
    179179            'php'                 => phpversion(),
    180180            'wordpress'           => UBDiagnostics::wordpress_version(),
    181             'plugin_version'      => '1.0.49',
     181            'plugin_version'      => '1.1.0',
    182182            'curl_installed'      => self::is_curl_installed(),
    183183            'xml_installed'       => self::is_xml_installed(),
    184             'sni_support'         => self::hasSNI(),
     184            'sni_support'         => self::has_sni(),
    185185            'permalink_structure' => get_option('permalink_structure'),
    186186            'domain'              => UBConfig::domain(),
  • unbounce/tags/1.1.0/UBHTTP.php

    r2823212 r2953445  
    77    public static $variant_url_regex = '/(.+)\/[a-z]+\.html/i';
    88    public static $pie_htc_url = '/PIE.htc';
    9     public static $request_header_blocklist = '/^(Accept-Encoding:)/i';
    10     public static $location_header_regex = '/^(Location:)/i';
     9    public static $request_header_blocklist = '/^(?:Accept-Encoding|Host|Forwarded)$/i';
     10    public static $location_header_regex = '/^(?:Location):/i';
    1111    public static $cookie_allowlist = array('ubvs', 'ubpv', 'ubvt', 'hubspotutk');
    1212    public static $response_headers_always_forwarded = array(
     
    1616        'location',
    1717        'link',
    18         'set-cookie'
     18        'set-cookie',
     19        'cf-ray',
     20        'cf-cache-status'
    1921    );
    2022
    21     public static function is_private_ip_address($ip_address)
    22     {
    23         return !filter_var(
     23    public static function is_public_ip_address($ip_address)
     24    {
     25        return filter_var(
    2426            $ip_address,
    2527            FILTER_VALIDATE_IP,
    2628            FILTER_FLAG_NO_PRIV_RANGE + FILTER_FLAG_NO_RES_RANGE
    2729        );
     30    }
     31
     32    // Removes last public IP address from an array of IP addresses, along with any private IP
     33    // addresses that come after it, as long as there is at least one remaining public IP address.
     34    private static function remove_last_public_ip_address($ip_addresses)
     35    {
     36        $public_ip_address_indexes = array();
     37        foreach ($ip_addresses as $index => $ip_address) {
     38            if (UBHTTP::is_public_ip_address($ip_address)) {
     39                $public_ip_address_indexes[] = $index;
     40            }
     41        }
     42
     43        if (count($public_ip_address_indexes) < 2) {
     44            return $ip_addresses;
     45        }
     46
     47        return array_slice(
     48            $ip_addresses,
     49            0,
     50            $public_ip_address_indexes[count($public_ip_address_indexes) - 1]
     51        );
     52    }
     53
     54    private static function get_last_public_ip_address($ip_addresses)
     55    {
     56        for ($i = count($ip_addresses) - 1; $i >= 0; $i--) {
     57            if (UBHTTP::is_public_ip_address($ip_addresses[$i])) {
     58                return $ip_addresses[$i];
     59            }
     60        }
     61        return null;
     62    }
     63
     64    private static function split_header_values($values)
     65    {
     66        return array_filter(array_map('trim', explode(',', $values ?: '')));
    2867    }
    2968
     
    4180    }
    4281
    43     private static function fetch_header_value_function($regex)
    44     {
    45         return function ($header_string) use ($regex) {
    46             $matches = array();
    47             preg_match(
    48                 $regex,
    49                 $header_string,
    50                 $matches
    51             );
    52             return $matches[1];
    53         };
    54     }
    55 
    56     public static function get_proxied_for_header(
    57         $forwarded_for,
    58         $current_ip
     82    public static function get_forwarded_headers(
     83        $domain,
     84        $current_protocol,
     85        $current_forwarded_for,
     86        $current_forwarded_proto,
     87        $current_remote_ip
    5988    ) {
    60         if ($forwarded_for !== null &&
    61          (UBConfig::allow_public_address_x_forwarded_for() ||
    62         UBHTTP::is_private_ip_address($current_ip))) {
    63             $proxied_for = $forwarded_for;
    64         } else {
    65             $proxied_for = $current_ip;
    66         }
    67         return array('X-Proxied-For' => $proxied_for);
     89        // X-Forwarded-For: preserve existing values so Page Server etc can see the full chain and
     90        // choose whether to use the leftmost (closest to first client) or rightmost (trusted) IP.
     91        // If this plugin has been configured to trust a proxy in front of it with a public IP
     92        // address, remove the last public IP address from the right, so the new rightmost value
     93        // will become the rightmost one set by that proxy.
     94        $current_forwarded_for = UBHTTP::split_header_values($current_forwarded_for);
     95        $target_forwarded_for = $current_forwarded_for;
     96        // In case the last X-Forwarded-For value matches the remote IP address, avoid appending a
     97        // duplicate value. It seems that this shouldn't be possible but it was observed with
     98        // Bluehost.
     99        if (UBUtil::array_fetch($current_forwarded_for, count($current_forwarded_for) - 1) !== $current_remote_ip) {
     100            $target_forwarded_for = array_merge($current_forwarded_for, array($current_remote_ip));
     101        }
     102        if (UBConfig::allow_public_address_x_forwarded_for()) {
     103            $target_forwarded_for = UBHTTP::remove_last_public_ip_address($target_forwarded_for);
     104        }
     105
     106        // X-Forwarded-Host: remove existing values so Page Server etc only see the configured
     107        // domain of this WordPress installation regardless of any proxies in front of it, because
     108        // this plugin should only be used to fetch content for that domain.
     109        $target_forwarded_host = $domain;
     110
     111        // X-Forwarded-Proto: preserve existing values so Page Server etc can see entire chain and
     112        // likely choose to use the leftmost value (closest to first client).
     113        $target_forwarded_proto = ($current_forwarded_proto ? $current_forwarded_proto . ', ' : '') .
     114            $current_protocol;
     115
     116        // X-Proxied-For: legacy header intended to contain a single trusted IP of the first client.
     117        $target_proxied_for = UBHTTP::get_last_public_ip_address($target_forwarded_for)
     118            ?: $target_forwarded_for[0];
     119
     120        return array(
     121            'x-forwarded-for' => implode(', ', $target_forwarded_for),
     122            'x-forwarded-host' => $target_forwarded_host,
     123            'x-forwarded-proto' => $target_forwarded_proto,
     124            'x-proxied-for' => $target_proxied_for
     125        );
    68126    }
    69127
     
    94152    }
    95153
     154    // Get protocol of current request from client to WordPress
     155    public static function get_current_protocol($server_global, $wp_is_ssl)
     156    {
     157        // Wordpress' is_ssl() may return the correct boolean for http/https if the site was set up
     158        // properly.
     159        $https = UBUtil::array_fetch($server_global, 'HTTPS', 'off');
     160        if ($wp_is_ssl || !is_null($https) && $https !== 'off') {
     161            return 'https';
     162        }
     163
     164        // Next use REQUEST_SCHEME, if it is available. This is the recommended way to get the
     165        // protocol, but it is not available on all hosts.
     166        $request_scheme = UBUtil::array_fetch($server_global, 'REQUEST_SCHEME');
     167        if (UBHTTP::is_valid_protocol($request_scheme)) {
     168            return $request_scheme;
     169        }
     170
     171        // Next try to pull it out of the SCRIPT_URI. This is also not always available.
     172        $script_uri = UBUtil::array_fetch($server_global, 'SCRIPT_URI');
     173        $script_uri_scheme = parse_url($script_uri, PHP_URL_SCHEME);
     174        if (UBHTTP::is_valid_protocol($script_uri_scheme)) {
     175            return $script_uri_scheme;
     176        }
     177
     178        // We default to http as most HTTPS sites will also have HTTP available.
     179        return 'http';
     180    }
     181
     182    // Determine protocol to use for request from WordPress to Page Server
    96183    public static function determine_protocol($server_global, $wp_is_ssl)
    97184    {
    98185        $forwarded_proto = UBUtil::array_fetch($server_global, 'HTTP_X_FORWARDED_PROTO');
     186        $first_valid_forwarded_proto = UBUtil::array_fetch(
     187            array_values(
     188                array_filter(
     189                    UBHTTP::split_header_values($forwarded_proto),
     190                    array('UBHTTP', 'is_valid_protocol')
     191                )
     192            ),
     193            0
     194        );
     195
    99196        $request_scheme = UBUtil::array_fetch($server_global, 'REQUEST_SCHEME');
    100197        $script_uri = UBUtil::array_fetch($server_global, 'SCRIPT_URI');
     
    103200
    104201        UBLogger::debug_var('UBHTTP::forwarded_proto', $forwarded_proto);
     202        UBLogger::debug_var('UBHTTP::first_valid_forwarded_proto', $first_valid_forwarded_proto);
    105203        UBLogger::debug_var('UBHTTP::request_scheme', $request_scheme);
    106204        UBLogger::debug_var('UBHTTP::script_uri', $script_uri);
     
    110208        // X-Forwarded-Proto should be respected first, as it is what the end
    111209        // user will see (if Wordpress is behind a load balancer).
    112         if (UBHTTP::is_valid_protocol($forwarded_proto)) {
    113             return $forwarded_proto . '://';
    114         } // Wordpress' is_ssl() may return the correct boolean for http/https if
    115         // the site was setup properly.
    116         elseif ($wp_is_ssl || !is_null($https) && $https !== 'off') {
    117             return 'https://';
    118         } // Next use REQUEST_SCHEME, if it is available. This is the recommended way
    119         // to get the protocol, but it is not available on all hosts.
    120         elseif (UBHTTP::is_valid_protocol($request_scheme)) {
    121             return $request_scheme . '://';
    122         } // Next try to pull it out of the SCRIPT_URI. This is also not always available.
    123         elseif (UBHTTP::is_valid_protocol($script_uri_scheme)) {
    124             return $script_uri_scheme . '://';
    125         } // We default to http as most HTTPS sites will also have HTTP available.
    126         else {
    127             return 'http://';
    128         }
     210        if ($first_valid_forwarded_proto) {
     211            return $first_valid_forwarded_proto;
     212        }
     213
     214        return UBHTTP::get_current_protocol($server_global, $wp_is_ssl);
    129215    }
    130216
     
    134220    }
    135221
    136   // taken from: http://stackoverflow.com/a/13036310/322727
     222    // taken from: http://stackoverflow.com/a/13036310/322727
    137223    public static function convert_headers_to_curl($headers)
    138224    {
     
    147233
    148234    public static function stream_request(
    149         $method,
     235        $target_method,
    150236        $target_url,
    151         $headers0,
    152         $user_agent
     237        $target_user_agent,
     238        $current_headers,
     239        $current_protocol,
     240        $domain
    153241    ) {
    154242        // Always add this header to responses to show it comes from our plugin.
     
    156244        if (UBConfig::use_curl()) {
    157245            return UBHTTP::stream_request_curl(
    158                 $method,
     246                $target_method,
    159247                $target_url,
    160                 $headers0,
    161                 $user_agent
     248                $target_user_agent,
     249                $current_headers,
     250                $current_protocol,
     251                $domain
    162252            );
    163253        } else {
    164254            return UBHTTP::stream_request_wp_remote(
    165                 $method,
     255                $target_method,
    166256                $target_url,
    167                 $headers0,
    168                 $user_agent
     257                $target_user_agent,
     258                $current_headers,
     259                $current_protocol,
     260                $domain
    169261            );
    170262        }
     
    172264
    173265    private static function stream_request_wp_remote(
    174         $method,
     266        $target_method,
    175267        $target_url,
    176         $headers0,
    177         $user_agent
     268        $target_user_agent,
     269        $current_headers,
     270        $current_protocol,
     271        $domain
    178272    ) {
    179273        $args = array(
    180             'method' => $method,
    181             'user-agent' => $user_agent,
     274            'method' => $target_method,
     275            'user-agent' => $target_user_agent,
    182276            'redirection' => 0,
    183277            'timeout' => 30,
    184             'headers' => UBHTTP::prepare_request_headers($headers0, true)
    185             );
    186         if ($method == 'POST') {
     278            'headers' => array_merge(
     279                UBHTTP::prepare_request_headers($current_headers, $current_protocol, $domain),
     280                array(
     281                    'x-ub-wordpress-remote-request' => '1',
     282                    'accept-encoding' => null
     283                )
     284            )
     285        );
     286        if ($target_method == 'POST') {
    187287            $args['body'] = file_get_contents('php://input');
    188288        }
     
    203303    }
    204304
    205     public static function prepare_request_headers($base_h)
    206     {
    207         $forwarded_for = UBUtil::array_fetch($_SERVER, 'HTTP_X_FORWARDED_FOR');
    208         $remote_ip = UBUtil::array_fetch($_SERVER, 'REMOTE_ADDR');
    209 
    210         $filtered_h = array();
    211         array_walk($base_h, function ($v, $k) use (&$filtered_h) {
    212             if (!preg_match(UBHTTP::$request_header_blocklist, $k . ": " . $v)) {
    213                 $filtered_h[$k] = $v;
     305    public static function prepare_request_headers($current_headers, $current_protocol, $domain)
     306    {
     307        $target_headers = array();
     308        array_walk($current_headers, function ($v, $k) use (&$target_headers) {
     309            if (!preg_match(UBHTTP::$request_header_blocklist, $k)) {
     310                $target_headers[$k] = $v;
    214311            }
    215312        });
    216313
    217         $filtered_h = UBHTTP::sanitize_cookies($filtered_h);
    218 
    219         $filtered_h = array_merge($filtered_h, UBHTTP::get_proxied_for_header(
    220             $forwarded_for,
    221             $remote_ip
    222         ), UBHTTP::get_diagnostic_headers());
    223 
    224         return $filtered_h;
    225     }
    226 
    227     private static function get_diagnostic_headers()
    228     {
    229         $headers = array('X-UB-WordPress-Plugin-Version' => '1.0.49');
     314        $current_forwarded_for = UBUtil::array_fetch($current_headers, 'x-forwarded-for');
     315        $current_forwarded_proto = UBUtil::array_fetch($current_headers, 'x-forwarded-proto');
     316        $current_remote_ip = UBUtil::array_fetch($_SERVER, 'REMOTE_ADDR');
     317
     318        return array_merge(
     319            UBHTTP::sanitize_cookies($target_headers),
     320            UBHTTP::get_forwarded_headers(
     321                $domain,
     322                $current_protocol,
     323                $current_forwarded_for,
     324                $current_forwarded_proto,
     325                $current_remote_ip
     326            ),
     327            UBHTTP::get_common_headers()
     328        );
     329    }
     330
     331    private static function get_common_headers()
     332    {
     333        $headers = array(
     334            'host' => UBConfig::page_server_domain(),
     335            'x-ub-wordpress-plugin-version' => '1.1.0'
     336        );
    230337
    231338        try {
     
    234341            // - 'r': Release name. eg. 5.4.39-linuxkit
    235342            // - 'm': Machine type. eg. x86_64
    236             $os_info = implode(' ', array_map('php_uname', ['s', 'r', 'm']));
     343            $os_info = implode(' ', array_map('php_uname', array('s', 'r', 'm')));
    237344            $curl_version = curl_version();
    238345            $headers = array_merge($headers, array(
    239                 'X-UB-WordPress-WordPress-Version' => UBDiagnostics::wordpress_version(),
    240                 'X-UB-WordPress-PHP-Version' => phpversion(),
    241                 'X-UB-WordPress-CURL-Version' => $curl_version['version'],
    242                 'X-UB-WordPress-SSL-Version' => $curl_version['ssl_version'],
    243                 'X-UB-WordPress-SNI-Support' => UBDiagnostics::hasSNI(),
    244                 'X-UB-WordPress-OS' => $os_info,
     346                'x-ub-wordpress-wordpress-version' => UBDiagnostics::wordpress_version(),
     347                'x-ub-wordpress-php-version' => phpversion(),
     348                'x-ub-wordpress-curl-version' => $curl_version['version'],
     349                'x-ub-wordpress-ssl-version' => $curl_version['ssl_version'],
     350                'x-ub-wordpress-allow-public-addr-xff' => UBConfig::allow_public_address_x_forwarded_for() ? '1' : '0',
     351                'x-ub-wordpress-os' => $os_info,
    245352            ));
    246353        } catch (Throwable $e) {
    247354            UBLogger::warning('Failed to build diagnostic headers: ' . $e);
     355        }
     356
     357        try {
     358            $headers['x-ub-wordpress-sni-support'] = UBDiagnostics::has_sni() ? '1' : '0';
     359        } catch (Throwable $e) {
     360            UBLogger::warning('Failed to build SNI diagnostic header: ' . $e);
    248361        }
    249362
     
    299412    }
    300413
    301 
    302414    private static function stream_request_curl(
    303         $method,
     415        $target_method,
    304416        $target_url,
    305         $headers0,
    306         $user_agent
     417        $target_user_agent,
     418        $current_headers,
     419        $current_protocol,
     420        $domain
    307421    ) {
    308422        $base_response_headers = headers_list();
    309423
    310         $headers1 = UBHTTP::prepare_request_headers($headers0);
    311         $headers = UBHTTP::convert_headers_to_curl($headers1);
     424        $target_headers = UBHTTP::prepare_request_headers($current_headers, $current_protocol, $domain);
     425        $target_headers = UBHTTP::convert_headers_to_curl($target_headers);
    312426
    313427        UBLogger::debug_var('target_url', $target_url);
    314         UBLogger::debug_var('original_headers', print_r($headers0, true));
    315         UBLogger::debug_var('sent_headers', print_r($headers, true));
     428        UBLogger::debug_var('current_headers', print_r($current_headers, true));
     429        UBLogger::debug_var('target_headers', print_r($target_headers, true));
    316430
    317431        $stream_headers = UBHTTP::stream_headers_function();
     
    321435        $curl_options = array(
    322436        CURLOPT_URL => $target_url,
    323         CURLOPT_POST => $method == "POST",
    324         CURLOPT_CUSTOMREQUEST => $method,
    325         CURLOPT_USERAGENT => $user_agent,
    326         CURLOPT_HTTPHEADER => $headers,
     437        CURLOPT_POST => $target_method == "POST",
     438        CURLOPT_CUSTOMREQUEST => $target_method,
     439        CURLOPT_USERAGENT => $target_user_agent,
     440        CURLOPT_HTTPHEADER => $target_headers,
    327441        CURLOPT_HEADERFUNCTION => $stream_headers,
    328442        CURLOPT_WRITEFUNCTION => $stream_body,
     
    331445        );
    332446
    333         if ($method == "POST") {
     447        if ($target_method == "POST") {
    334448            // Use raw post body to allow the same post key to occur more than once
    335449            $curl_options[CURLOPT_POSTFIELDS] = file_get_contents('php://input');
  • unbounce/tags/1.1.0/Unbounce-Page.php

    r2823212 r2953445  
    44Plugin URI: http://unbounce.com
    55Description: Unbounce is the most powerful standalone landing page builder available.
    6 Version: 1.0.49
     6Version: 1.1.0
    77Author: Unbounce
    88Author URI: http://unbounce.com
     
    4141    }
    4242
     43    UBLogger::debug_var('domain', $domain);
     44
    4345    $start = microtime(true);
    4446
    45     $ps_domain = UBConfig::page_server_domain();
    46     $http_method = UBUtil::array_fetch($_SERVER, 'REQUEST_METHOD');
    47     $referer = UBUtil::array_fetch($_SERVER, 'HTTP_REFERER');
    48     $user_agent = UBUtil::array_fetch($_SERVER, 'HTTP_USER_AGENT');
    49     $protocol = UBHTTP::determine_protocol($_SERVER, is_ssl());
     47    // $current_* = request from client to WordPress
     48    // $target_*  = request from WordPress to Page Server
     49
     50    $current_protocol = UBHTTP::get_current_protocol($_SERVER, is_ssl());
     51    $current_method = UBUtil::array_fetch($_SERVER, 'REQUEST_METHOD');
    5052    $current_path = UBUtil::array_fetch($_SERVER, 'REQUEST_URI');
    51 
    52     $raw_url = $protocol . $ps_domain . $current_path;
    53     $current_url  = $protocol . $domain . $current_path;
     53    $current_url  = $current_protocol . '://' . $domain . $current_path;
     54    $current_user_agent = UBUtil::array_fetch($_SERVER, 'HTTP_USER_AGENT');
     55
     56    UBLogger::debug_var('current_protocol', $current_protocol);
     57    UBLogger::debug_var('current_method', $current_method);
     58    UBLogger::debug_var('current_path', $current_path);
     59    UBLogger::debug_var('current_url', $current_url);
     60    UBLogger::debug_var('current_user_agent', $current_user_agent);
     61
     62    $target_protocol = UBHTTP::determine_protocol($_SERVER, is_ssl());
     63    $target_domain = UBConfig::page_server_domain();
     64    $target_url = $target_protocol . '://' . $target_domain . $current_path;
     65
     66    UBLogger::debug_var('target_domain', $target_domain);
     67    UBLogger::debug_var('target_protocol', $target_protocol);
     68    UBLogger::debug_var('target_url', $target_url);
    5469
    5570    $domain_info = UBConfig::read_unbounce_domain_info($domain, false);
    5671    $proxyable_url_set = UBUtil::array_fetch($domain_info, 'proxyable_url_set', array());
    5772
    58     UBLogger::debug_var('ps_domain', $ps_domain);
    59     UBLogger::debug_var('http_method', $http_method);
    60     UBLogger::debug_var('referer', $referer);
    61     UBLogger::debug_var('user_agent', $user_agent);
    62     UBLogger::debug_var('protocol', $protocol);
    63     UBLogger::debug_var('domain', $domain);
    64     UBLogger::debug_var('current_path', $current_path);
    65     UBLogger::debug_var('raw_url', $raw_url);
    66     UBLogger::debug_var('current_url', $current_url);
    67 
    68   ////////////////////
     73    ////////////////////
    6974
    7075    $url_purpose = UBHTTP::get_url_purpose(
    7176        $proxyable_url_set,
    72         $http_method,
     77        $current_method,
    7378        $current_url
    7479    );
     
    113118        UBLogger::debug("perform ''" . $url_purpose . "'' on received URL " . $current_url);
    114119
    115         $all_headers = getallheaders();
    116         $all_headers['Host'] = $domain;
     120        $current_headers = array_change_key_case(getallheaders(), CASE_LOWER);
    117121
    118122        // Make sure we don't get cached by Wordpress hosts like WPEngine
     
    120124
    121125        list($success, $message) = UBHTTP::stream_request(
    122             $http_method,
    123             $raw_url,
    124             $all_headers,
    125             $user_agent
     126            $current_method,
     127            $target_url,
     128            $current_user_agent,
     129            $current_headers,
     130            $current_protocol,
     131            $domain
    126132        );
    127133
     
    134140
    135141        UBLogger::debug_var('time_taken', $time_taken);
    136         UBLogger::debug("proxying for $current_url done successfuly -- took $time_taken ms");
     142        UBLogger::debug("proxying for $current_url done successfully -- took $time_taken ms");
    137143
    138144        exit(0);
     
    141147
    142148add_action('admin_init', function () {
    143 
    144     $pluginVersion = get_option(UBConfig::UB_PLUGIN_VERSION_KEY);
    145     if (UBConfig::UB_VERSION != $pluginVersion) {
     149    $current_version = UBConfig::UB_VERSION;
     150
     151    if (get_option(UBConfig::UB_PLUGIN_VERSION_KEY) != $current_version) {
    146152        UBConfig::set_options_if_not_exist();
    147         update_option(UBConfig::UB_PLUGIN_VERSION_KEY, UBConfig::UB_VERSION);
     153        update_option(UBConfig::UB_PLUGIN_VERSION_KEY, $current_version);
     154
     155        // When upgrading to 1.1.0, override all previous ub-page-server-domain values to new default
     156        // TODO: Remove this in subsequent plugin versions
     157        update_option(UBConfig::UB_PAGE_SERVER_DOMAIN_KEY, UBConfig::default_page_server_domain());
    148158    }
    149159
     
    208218        'Response Headers Forwarded',
    209219        function ($args) {
     220            $defaults = UBConfig::ub_option_defaults();
    210221            echo UBTemplate::render('settings_response_headers_forwarded', array(
    211222                'value' => get_option(UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY),
    212                 'default' => UBConfig::ub_option_defaults()[UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY]
     223                'default' => $defaults[UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY]
    213224            ));
    214225        },
  • unbounce/tags/1.1.0/readme.txt

    r2823212 r2953445  
    33Tags: Unbounce, AB testing, A/B testing, split testing, CRO, conversion optimization, wordpress landing page, wp landing pages, splash pages, landing pages, squeeze pages, lead gen, lead generation, email list, responsive landing pages, templates, inbound marketing, ppc, analytics
    44Requires at least: 4.1.5
    5 Tested up to: 6.0.2
    6 Stable tag: 1.0.49
     5Tested up to: 6.3
     6Stable tag: 1.1.0
    77Requires PHP: 7.2
    88License: GPLv2 or later
     
    104104== Changelog ==
    105105
     106= 1.1.0 =
     107* Changes the method used to communicate with Unbounce servers, which will improve the resilience of
     108  your pages to denial-of-service attacks
     109* Tested with WP 6.3
     110* **Important**: please upgrade to this version as soon as possible to benefit from these
     111  improvements. All older versions are now unsupported and will stop working in the near future.
     112
    106113= 1.0.49 =
    107114* Added setting to customize response headers forwarded from Unbounce
  • unbounce/tags/1.1.0/templates/diagnostics.php

    r2823212 r2953445  
    77                      <li>Domain is not added in Unbounce account you are using to authorize. Make sure that the domain is present in a client you are the owner or administrator for.</li>
    88                      <li>Domain in Unbounce does not match WP configured domain (i.e. has, or does not have www.). The domain listed in Unbounce must match the WP domain exactly, so if it is configured to be www.domain.com, then that should be what is listed in the domain portion of your Unbounce account.</li>
    9                       <li>In order to connect with Unbounce, we need to validate the cert for wp.unbounce.com. Please make sure that your CA Cert file is up to date, as an out of date CA Cert file can cause the connection to fail</li>
     9                      <li>In order to connect with Unbounce, we need to validate the cert for proxy.unbouncepages.com. Please make sure that your CA Cert file is up to date, as an out of date CA Cert file can cause the connection to fail</li>
    1010                      </ul>
    1111                      For more troubleshooting information please read our <a href=\"https://documentation.unbounce.com/hc/en-us/articles/360000393623-Troubleshooting-WordPress-Plugin-Technical-Issues\" target=\"_blank\">Support Article</a>";
  • unbounce/tags/1.1.0/templates/main_authorized_footer.php

    r2823212 r2953445  
    2222  Click here for troubleshooting and plugin diagnostics
    2323</a>
    24 <p class="ub-version">Unbounce Version 1.0.49</p>
     24<p class="ub-version">Unbounce Version 1.1.0</p>
  • unbounce/tags/1.1.0/templates/main_unauthorized_footer.php

    r2823212 r2953445  
    55  Click here for troubleshooting and plugin diagnostics
    66</a>
    7 <p class="ub-version">Unbounce Version 1.0.49</p>
     7<p class="ub-version">Unbounce Version 1.1.0</p>
  • unbounce/trunk/UBConfig.php

    r2823212 r2953445  
    66    const UB_PLUGIN_NAME           = 'ub-wordpress';
    77    const UB_CACHE_TIMEOUT_ENV_KEY = 'UB_WP_ROUTES_CACHE_EXP';
    8     const UB_USER_AGENT            = 'Unbounce WP Plugin 1.0.49';
    9     const UB_VERSION               = '1.0.49';
     8    const UB_USER_AGENT            = 'Unbounce WP Plugin 1.1.0';
     9    const UB_VERSION               = '1.1.0';
    1010
    1111    // WP Admin Pages
     
    7373    {
    7474        $domain = getenv('UB_PAGE_SERVER_DOMAIN');
    75         return $domain ? $domain : 'wp.unbounce.com';
     75        return $domain ? $domain : 'proxy.unbouncepages.com';
    7676    }
    7777
     
    189189            $curl = curl_init();
    190190            $curl_options = array(
    191             CURLOPT_URL => $url,
    192             CURLOPT_CUSTOMREQUEST => "GET",
    193             CURLOPT_HEADER => true,
    194             CURLOPT_USERAGENT => UBConfig::UB_USER_AGENT,
    195             CURLOPT_HTTPHEADER => array('Host: ' . $domain, 'If-None-Match: ' . $etag),
    196             CURLOPT_RETURNTRANSFER => true,
    197             CURLOPT_FOLLOWLOCATION => false,
    198             CURLOPT_TIMEOUT => 5
     191                CURLOPT_URL => $url,
     192                CURLOPT_CUSTOMREQUEST => "GET",
     193                CURLOPT_HEADER => true,
     194                CURLOPT_USERAGENT => UBConfig::UB_USER_AGENT,
     195                CURLOPT_HTTPHEADER => UBHTTP::convert_headers_to_curl(
     196                    array(
     197                        'x-forwarded-host' => $domain,
     198                        'if-none-match' => $etag
     199                    )
     200                ),
     201                CURLOPT_RETURNTRANSFER => true,
     202                CURLOPT_FOLLOWLOCATION => false,
     203                CURLOPT_TIMEOUT => 5
    199204            );
    200205
  • unbounce/trunk/UBDiagnostics.php

    r2823212 r2953445  
    3535                '>='
    3636            ),
    37             'SNI Support' => self::hasSNI(),
    38         );
    39     }
    40 
    41     public static function hasSNI()
     37            'SNI Support' => self::has_sni(),
     38        );
     39    }
     40
     41    public static function has_sni()
    4242    {
    4343        return defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME;
     
    101101        'PHP Version'             => phpversion(),
    102102        'WordPress Version'       => UBDiagnostics::wordpress_version(),
    103         'Unbounce Plugin Version' => '1.0.49',
     103        'Unbounce Plugin Version' => '1.1.0',
    104104        'Checks'                  => self::pp(UBDiagnostics::checks($domain, $domain_info)),
    105105        'Options'                 => self::pp(UBDiagnostics::ub_options()),
     
    111111        'Plugin Details'          => self::pp(get_plugins()),
    112112        'Curl Version'            => self::pp(UBDiagnostics::curl_version()),
    113         'SNI Support'             => self::hasSNI(),
     113        'SNI Support'             => self::has_sni(),
    114114        'Configuration Options'   => self::pp(self::phpConfig()),
    115115        'Extensions'              => self::pp(get_loaded_extensions()),
     
    179179            'php'                 => phpversion(),
    180180            'wordpress'           => UBDiagnostics::wordpress_version(),
    181             'plugin_version'      => '1.0.49',
     181            'plugin_version'      => '1.1.0',
    182182            'curl_installed'      => self::is_curl_installed(),
    183183            'xml_installed'       => self::is_xml_installed(),
    184             'sni_support'         => self::hasSNI(),
     184            'sni_support'         => self::has_sni(),
    185185            'permalink_structure' => get_option('permalink_structure'),
    186186            'domain'              => UBConfig::domain(),
  • unbounce/trunk/UBHTTP.php

    r2823212 r2953445  
    77    public static $variant_url_regex = '/(.+)\/[a-z]+\.html/i';
    88    public static $pie_htc_url = '/PIE.htc';
    9     public static $request_header_blocklist = '/^(Accept-Encoding:)/i';
    10     public static $location_header_regex = '/^(Location:)/i';
     9    public static $request_header_blocklist = '/^(?:Accept-Encoding|Host|Forwarded)$/i';
     10    public static $location_header_regex = '/^(?:Location):/i';
    1111    public static $cookie_allowlist = array('ubvs', 'ubpv', 'ubvt', 'hubspotutk');
    1212    public static $response_headers_always_forwarded = array(
     
    1616        'location',
    1717        'link',
    18         'set-cookie'
     18        'set-cookie',
     19        'cf-ray',
     20        'cf-cache-status'
    1921    );
    2022
    21     public static function is_private_ip_address($ip_address)
    22     {
    23         return !filter_var(
     23    public static function is_public_ip_address($ip_address)
     24    {
     25        return filter_var(
    2426            $ip_address,
    2527            FILTER_VALIDATE_IP,
    2628            FILTER_FLAG_NO_PRIV_RANGE + FILTER_FLAG_NO_RES_RANGE
    2729        );
     30    }
     31
     32    // Removes last public IP address from an array of IP addresses, along with any private IP
     33    // addresses that come after it, as long as there is at least one remaining public IP address.
     34    private static function remove_last_public_ip_address($ip_addresses)
     35    {
     36        $public_ip_address_indexes = array();
     37        foreach ($ip_addresses as $index => $ip_address) {
     38            if (UBHTTP::is_public_ip_address($ip_address)) {
     39                $public_ip_address_indexes[] = $index;
     40            }
     41        }
     42
     43        if (count($public_ip_address_indexes) < 2) {
     44            return $ip_addresses;
     45        }
     46
     47        return array_slice(
     48            $ip_addresses,
     49            0,
     50            $public_ip_address_indexes[count($public_ip_address_indexes) - 1]
     51        );
     52    }
     53
     54    private static function get_last_public_ip_address($ip_addresses)
     55    {
     56        for ($i = count($ip_addresses) - 1; $i >= 0; $i--) {
     57            if (UBHTTP::is_public_ip_address($ip_addresses[$i])) {
     58                return $ip_addresses[$i];
     59            }
     60        }
     61        return null;
     62    }
     63
     64    private static function split_header_values($values)
     65    {
     66        return array_filter(array_map('trim', explode(',', $values ?: '')));
    2867    }
    2968
     
    4180    }
    4281
    43     private static function fetch_header_value_function($regex)
    44     {
    45         return function ($header_string) use ($regex) {
    46             $matches = array();
    47             preg_match(
    48                 $regex,
    49                 $header_string,
    50                 $matches
    51             );
    52             return $matches[1];
    53         };
    54     }
    55 
    56     public static function get_proxied_for_header(
    57         $forwarded_for,
    58         $current_ip
     82    public static function get_forwarded_headers(
     83        $domain,
     84        $current_protocol,
     85        $current_forwarded_for,
     86        $current_forwarded_proto,
     87        $current_remote_ip
    5988    ) {
    60         if ($forwarded_for !== null &&
    61          (UBConfig::allow_public_address_x_forwarded_for() ||
    62         UBHTTP::is_private_ip_address($current_ip))) {
    63             $proxied_for = $forwarded_for;
    64         } else {
    65             $proxied_for = $current_ip;
    66         }
    67         return array('X-Proxied-For' => $proxied_for);
     89        // X-Forwarded-For: preserve existing values so Page Server etc can see the full chain and
     90        // choose whether to use the leftmost (closest to first client) or rightmost (trusted) IP.
     91        // If this plugin has been configured to trust a proxy in front of it with a public IP
     92        // address, remove the last public IP address from the right, so the new rightmost value
     93        // will become the rightmost one set by that proxy.
     94        $current_forwarded_for = UBHTTP::split_header_values($current_forwarded_for);
     95        $target_forwarded_for = $current_forwarded_for;
     96        // In case the last X-Forwarded-For value matches the remote IP address, avoid appending a
     97        // duplicate value. It seems that this shouldn't be possible but it was observed with
     98        // Bluehost.
     99        if (UBUtil::array_fetch($current_forwarded_for, count($current_forwarded_for) - 1) !== $current_remote_ip) {
     100            $target_forwarded_for = array_merge($current_forwarded_for, array($current_remote_ip));
     101        }
     102        if (UBConfig::allow_public_address_x_forwarded_for()) {
     103            $target_forwarded_for = UBHTTP::remove_last_public_ip_address($target_forwarded_for);
     104        }
     105
     106        // X-Forwarded-Host: remove existing values so Page Server etc only see the configured
     107        // domain of this WordPress installation regardless of any proxies in front of it, because
     108        // this plugin should only be used to fetch content for that domain.
     109        $target_forwarded_host = $domain;
     110
     111        // X-Forwarded-Proto: preserve existing values so Page Server etc can see entire chain and
     112        // likely choose to use the leftmost value (closest to first client).
     113        $target_forwarded_proto = ($current_forwarded_proto ? $current_forwarded_proto . ', ' : '') .
     114            $current_protocol;
     115
     116        // X-Proxied-For: legacy header intended to contain a single trusted IP of the first client.
     117        $target_proxied_for = UBHTTP::get_last_public_ip_address($target_forwarded_for)
     118            ?: $target_forwarded_for[0];
     119
     120        return array(
     121            'x-forwarded-for' => implode(', ', $target_forwarded_for),
     122            'x-forwarded-host' => $target_forwarded_host,
     123            'x-forwarded-proto' => $target_forwarded_proto,
     124            'x-proxied-for' => $target_proxied_for
     125        );
    68126    }
    69127
     
    94152    }
    95153
     154    // Get protocol of current request from client to WordPress
     155    public static function get_current_protocol($server_global, $wp_is_ssl)
     156    {
     157        // Wordpress' is_ssl() may return the correct boolean for http/https if the site was set up
     158        // properly.
     159        $https = UBUtil::array_fetch($server_global, 'HTTPS', 'off');
     160        if ($wp_is_ssl || !is_null($https) && $https !== 'off') {
     161            return 'https';
     162        }
     163
     164        // Next use REQUEST_SCHEME, if it is available. This is the recommended way to get the
     165        // protocol, but it is not available on all hosts.
     166        $request_scheme = UBUtil::array_fetch($server_global, 'REQUEST_SCHEME');
     167        if (UBHTTP::is_valid_protocol($request_scheme)) {
     168            return $request_scheme;
     169        }
     170
     171        // Next try to pull it out of the SCRIPT_URI. This is also not always available.
     172        $script_uri = UBUtil::array_fetch($server_global, 'SCRIPT_URI');
     173        $script_uri_scheme = parse_url($script_uri, PHP_URL_SCHEME);
     174        if (UBHTTP::is_valid_protocol($script_uri_scheme)) {
     175            return $script_uri_scheme;
     176        }
     177
     178        // We default to http as most HTTPS sites will also have HTTP available.
     179        return 'http';
     180    }
     181
     182    // Determine protocol to use for request from WordPress to Page Server
    96183    public static function determine_protocol($server_global, $wp_is_ssl)
    97184    {
    98185        $forwarded_proto = UBUtil::array_fetch($server_global, 'HTTP_X_FORWARDED_PROTO');
     186        $first_valid_forwarded_proto = UBUtil::array_fetch(
     187            array_values(
     188                array_filter(
     189                    UBHTTP::split_header_values($forwarded_proto),
     190                    array('UBHTTP', 'is_valid_protocol')
     191                )
     192            ),
     193            0
     194        );
     195
    99196        $request_scheme = UBUtil::array_fetch($server_global, 'REQUEST_SCHEME');
    100197        $script_uri = UBUtil::array_fetch($server_global, 'SCRIPT_URI');
     
    103200
    104201        UBLogger::debug_var('UBHTTP::forwarded_proto', $forwarded_proto);
     202        UBLogger::debug_var('UBHTTP::first_valid_forwarded_proto', $first_valid_forwarded_proto);
    105203        UBLogger::debug_var('UBHTTP::request_scheme', $request_scheme);
    106204        UBLogger::debug_var('UBHTTP::script_uri', $script_uri);
     
    110208        // X-Forwarded-Proto should be respected first, as it is what the end
    111209        // user will see (if Wordpress is behind a load balancer).
    112         if (UBHTTP::is_valid_protocol($forwarded_proto)) {
    113             return $forwarded_proto . '://';
    114         } // Wordpress' is_ssl() may return the correct boolean for http/https if
    115         // the site was setup properly.
    116         elseif ($wp_is_ssl || !is_null($https) && $https !== 'off') {
    117             return 'https://';
    118         } // Next use REQUEST_SCHEME, if it is available. This is the recommended way
    119         // to get the protocol, but it is not available on all hosts.
    120         elseif (UBHTTP::is_valid_protocol($request_scheme)) {
    121             return $request_scheme . '://';
    122         } // Next try to pull it out of the SCRIPT_URI. This is also not always available.
    123         elseif (UBHTTP::is_valid_protocol($script_uri_scheme)) {
    124             return $script_uri_scheme . '://';
    125         } // We default to http as most HTTPS sites will also have HTTP available.
    126         else {
    127             return 'http://';
    128         }
     210        if ($first_valid_forwarded_proto) {
     211            return $first_valid_forwarded_proto;
     212        }
     213
     214        return UBHTTP::get_current_protocol($server_global, $wp_is_ssl);
    129215    }
    130216
     
    134220    }
    135221
    136   // taken from: http://stackoverflow.com/a/13036310/322727
     222    // taken from: http://stackoverflow.com/a/13036310/322727
    137223    public static function convert_headers_to_curl($headers)
    138224    {
     
    147233
    148234    public static function stream_request(
    149         $method,
     235        $target_method,
    150236        $target_url,
    151         $headers0,
    152         $user_agent
     237        $target_user_agent,
     238        $current_headers,
     239        $current_protocol,
     240        $domain
    153241    ) {
    154242        // Always add this header to responses to show it comes from our plugin.
     
    156244        if (UBConfig::use_curl()) {
    157245            return UBHTTP::stream_request_curl(
    158                 $method,
     246                $target_method,
    159247                $target_url,
    160                 $headers0,
    161                 $user_agent
     248                $target_user_agent,
     249                $current_headers,
     250                $current_protocol,
     251                $domain
    162252            );
    163253        } else {
    164254            return UBHTTP::stream_request_wp_remote(
    165                 $method,
     255                $target_method,
    166256                $target_url,
    167                 $headers0,
    168                 $user_agent
     257                $target_user_agent,
     258                $current_headers,
     259                $current_protocol,
     260                $domain
    169261            );
    170262        }
     
    172264
    173265    private static function stream_request_wp_remote(
    174         $method,
     266        $target_method,
    175267        $target_url,
    176         $headers0,
    177         $user_agent
     268        $target_user_agent,
     269        $current_headers,
     270        $current_protocol,
     271        $domain
    178272    ) {
    179273        $args = array(
    180             'method' => $method,
    181             'user-agent' => $user_agent,
     274            'method' => $target_method,
     275            'user-agent' => $target_user_agent,
    182276            'redirection' => 0,
    183277            'timeout' => 30,
    184             'headers' => UBHTTP::prepare_request_headers($headers0, true)
    185             );
    186         if ($method == 'POST') {
     278            'headers' => array_merge(
     279                UBHTTP::prepare_request_headers($current_headers, $current_protocol, $domain),
     280                array(
     281                    'x-ub-wordpress-remote-request' => '1',
     282                    'accept-encoding' => null
     283                )
     284            )
     285        );
     286        if ($target_method == 'POST') {
    187287            $args['body'] = file_get_contents('php://input');
    188288        }
     
    203303    }
    204304
    205     public static function prepare_request_headers($base_h)
    206     {
    207         $forwarded_for = UBUtil::array_fetch($_SERVER, 'HTTP_X_FORWARDED_FOR');
    208         $remote_ip = UBUtil::array_fetch($_SERVER, 'REMOTE_ADDR');
    209 
    210         $filtered_h = array();
    211         array_walk($base_h, function ($v, $k) use (&$filtered_h) {
    212             if (!preg_match(UBHTTP::$request_header_blocklist, $k . ": " . $v)) {
    213                 $filtered_h[$k] = $v;
     305    public static function prepare_request_headers($current_headers, $current_protocol, $domain)
     306    {
     307        $target_headers = array();
     308        array_walk($current_headers, function ($v, $k) use (&$target_headers) {
     309            if (!preg_match(UBHTTP::$request_header_blocklist, $k)) {
     310                $target_headers[$k] = $v;
    214311            }
    215312        });
    216313
    217         $filtered_h = UBHTTP::sanitize_cookies($filtered_h);
    218 
    219         $filtered_h = array_merge($filtered_h, UBHTTP::get_proxied_for_header(
    220             $forwarded_for,
    221             $remote_ip
    222         ), UBHTTP::get_diagnostic_headers());
    223 
    224         return $filtered_h;
    225     }
    226 
    227     private static function get_diagnostic_headers()
    228     {
    229         $headers = array('X-UB-WordPress-Plugin-Version' => '1.0.49');
     314        $current_forwarded_for = UBUtil::array_fetch($current_headers, 'x-forwarded-for');
     315        $current_forwarded_proto = UBUtil::array_fetch($current_headers, 'x-forwarded-proto');
     316        $current_remote_ip = UBUtil::array_fetch($_SERVER, 'REMOTE_ADDR');
     317
     318        return array_merge(
     319            UBHTTP::sanitize_cookies($target_headers),
     320            UBHTTP::get_forwarded_headers(
     321                $domain,
     322                $current_protocol,
     323                $current_forwarded_for,
     324                $current_forwarded_proto,
     325                $current_remote_ip
     326            ),
     327            UBHTTP::get_common_headers()
     328        );
     329    }
     330
     331    private static function get_common_headers()
     332    {
     333        $headers = array(
     334            'host' => UBConfig::page_server_domain(),
     335            'x-ub-wordpress-plugin-version' => '1.1.0'
     336        );
    230337
    231338        try {
     
    234341            // - 'r': Release name. eg. 5.4.39-linuxkit
    235342            // - 'm': Machine type. eg. x86_64
    236             $os_info = implode(' ', array_map('php_uname', ['s', 'r', 'm']));
     343            $os_info = implode(' ', array_map('php_uname', array('s', 'r', 'm')));
    237344            $curl_version = curl_version();
    238345            $headers = array_merge($headers, array(
    239                 'X-UB-WordPress-WordPress-Version' => UBDiagnostics::wordpress_version(),
    240                 'X-UB-WordPress-PHP-Version' => phpversion(),
    241                 'X-UB-WordPress-CURL-Version' => $curl_version['version'],
    242                 'X-UB-WordPress-SSL-Version' => $curl_version['ssl_version'],
    243                 'X-UB-WordPress-SNI-Support' => UBDiagnostics::hasSNI(),
    244                 'X-UB-WordPress-OS' => $os_info,
     346                'x-ub-wordpress-wordpress-version' => UBDiagnostics::wordpress_version(),
     347                'x-ub-wordpress-php-version' => phpversion(),
     348                'x-ub-wordpress-curl-version' => $curl_version['version'],
     349                'x-ub-wordpress-ssl-version' => $curl_version['ssl_version'],
     350                'x-ub-wordpress-allow-public-addr-xff' => UBConfig::allow_public_address_x_forwarded_for() ? '1' : '0',
     351                'x-ub-wordpress-os' => $os_info,
    245352            ));
    246353        } catch (Throwable $e) {
    247354            UBLogger::warning('Failed to build diagnostic headers: ' . $e);
     355        }
     356
     357        try {
     358            $headers['x-ub-wordpress-sni-support'] = UBDiagnostics::has_sni() ? '1' : '0';
     359        } catch (Throwable $e) {
     360            UBLogger::warning('Failed to build SNI diagnostic header: ' . $e);
    248361        }
    249362
     
    299412    }
    300413
    301 
    302414    private static function stream_request_curl(
    303         $method,
     415        $target_method,
    304416        $target_url,
    305         $headers0,
    306         $user_agent
     417        $target_user_agent,
     418        $current_headers,
     419        $current_protocol,
     420        $domain
    307421    ) {
    308422        $base_response_headers = headers_list();
    309423
    310         $headers1 = UBHTTP::prepare_request_headers($headers0);
    311         $headers = UBHTTP::convert_headers_to_curl($headers1);
     424        $target_headers = UBHTTP::prepare_request_headers($current_headers, $current_protocol, $domain);
     425        $target_headers = UBHTTP::convert_headers_to_curl($target_headers);
    312426
    313427        UBLogger::debug_var('target_url', $target_url);
    314         UBLogger::debug_var('original_headers', print_r($headers0, true));
    315         UBLogger::debug_var('sent_headers', print_r($headers, true));
     428        UBLogger::debug_var('current_headers', print_r($current_headers, true));
     429        UBLogger::debug_var('target_headers', print_r($target_headers, true));
    316430
    317431        $stream_headers = UBHTTP::stream_headers_function();
     
    321435        $curl_options = array(
    322436        CURLOPT_URL => $target_url,
    323         CURLOPT_POST => $method == "POST",
    324         CURLOPT_CUSTOMREQUEST => $method,
    325         CURLOPT_USERAGENT => $user_agent,
    326         CURLOPT_HTTPHEADER => $headers,
     437        CURLOPT_POST => $target_method == "POST",
     438        CURLOPT_CUSTOMREQUEST => $target_method,
     439        CURLOPT_USERAGENT => $target_user_agent,
     440        CURLOPT_HTTPHEADER => $target_headers,
    327441        CURLOPT_HEADERFUNCTION => $stream_headers,
    328442        CURLOPT_WRITEFUNCTION => $stream_body,
     
    331445        );
    332446
    333         if ($method == "POST") {
     447        if ($target_method == "POST") {
    334448            // Use raw post body to allow the same post key to occur more than once
    335449            $curl_options[CURLOPT_POSTFIELDS] = file_get_contents('php://input');
  • unbounce/trunk/Unbounce-Page.php

    r2823212 r2953445  
    44Plugin URI: http://unbounce.com
    55Description: Unbounce is the most powerful standalone landing page builder available.
    6 Version: 1.0.49
     6Version: 1.1.0
    77Author: Unbounce
    88Author URI: http://unbounce.com
     
    4141    }
    4242
     43    UBLogger::debug_var('domain', $domain);
     44
    4345    $start = microtime(true);
    4446
    45     $ps_domain = UBConfig::page_server_domain();
    46     $http_method = UBUtil::array_fetch($_SERVER, 'REQUEST_METHOD');
    47     $referer = UBUtil::array_fetch($_SERVER, 'HTTP_REFERER');
    48     $user_agent = UBUtil::array_fetch($_SERVER, 'HTTP_USER_AGENT');
    49     $protocol = UBHTTP::determine_protocol($_SERVER, is_ssl());
     47    // $current_* = request from client to WordPress
     48    // $target_*  = request from WordPress to Page Server
     49
     50    $current_protocol = UBHTTP::get_current_protocol($_SERVER, is_ssl());
     51    $current_method = UBUtil::array_fetch($_SERVER, 'REQUEST_METHOD');
    5052    $current_path = UBUtil::array_fetch($_SERVER, 'REQUEST_URI');
    51 
    52     $raw_url = $protocol . $ps_domain . $current_path;
    53     $current_url  = $protocol . $domain . $current_path;
     53    $current_url  = $current_protocol . '://' . $domain . $current_path;
     54    $current_user_agent = UBUtil::array_fetch($_SERVER, 'HTTP_USER_AGENT');
     55
     56    UBLogger::debug_var('current_protocol', $current_protocol);
     57    UBLogger::debug_var('current_method', $current_method);
     58    UBLogger::debug_var('current_path', $current_path);
     59    UBLogger::debug_var('current_url', $current_url);
     60    UBLogger::debug_var('current_user_agent', $current_user_agent);
     61
     62    $target_protocol = UBHTTP::determine_protocol($_SERVER, is_ssl());
     63    $target_domain = UBConfig::page_server_domain();
     64    $target_url = $target_protocol . '://' . $target_domain . $current_path;
     65
     66    UBLogger::debug_var('target_domain', $target_domain);
     67    UBLogger::debug_var('target_protocol', $target_protocol);
     68    UBLogger::debug_var('target_url', $target_url);
    5469
    5570    $domain_info = UBConfig::read_unbounce_domain_info($domain, false);
    5671    $proxyable_url_set = UBUtil::array_fetch($domain_info, 'proxyable_url_set', array());
    5772
    58     UBLogger::debug_var('ps_domain', $ps_domain);
    59     UBLogger::debug_var('http_method', $http_method);
    60     UBLogger::debug_var('referer', $referer);
    61     UBLogger::debug_var('user_agent', $user_agent);
    62     UBLogger::debug_var('protocol', $protocol);
    63     UBLogger::debug_var('domain', $domain);
    64     UBLogger::debug_var('current_path', $current_path);
    65     UBLogger::debug_var('raw_url', $raw_url);
    66     UBLogger::debug_var('current_url', $current_url);
    67 
    68   ////////////////////
     73    ////////////////////
    6974
    7075    $url_purpose = UBHTTP::get_url_purpose(
    7176        $proxyable_url_set,
    72         $http_method,
     77        $current_method,
    7378        $current_url
    7479    );
     
    113118        UBLogger::debug("perform ''" . $url_purpose . "'' on received URL " . $current_url);
    114119
    115         $all_headers = getallheaders();
    116         $all_headers['Host'] = $domain;
     120        $current_headers = array_change_key_case(getallheaders(), CASE_LOWER);
    117121
    118122        // Make sure we don't get cached by Wordpress hosts like WPEngine
     
    120124
    121125        list($success, $message) = UBHTTP::stream_request(
    122             $http_method,
    123             $raw_url,
    124             $all_headers,
    125             $user_agent
     126            $current_method,
     127            $target_url,
     128            $current_user_agent,
     129            $current_headers,
     130            $current_protocol,
     131            $domain
    126132        );
    127133
     
    134140
    135141        UBLogger::debug_var('time_taken', $time_taken);
    136         UBLogger::debug("proxying for $current_url done successfuly -- took $time_taken ms");
     142        UBLogger::debug("proxying for $current_url done successfully -- took $time_taken ms");
    137143
    138144        exit(0);
     
    141147
    142148add_action('admin_init', function () {
    143 
    144     $pluginVersion = get_option(UBConfig::UB_PLUGIN_VERSION_KEY);
    145     if (UBConfig::UB_VERSION != $pluginVersion) {
     149    $current_version = UBConfig::UB_VERSION;
     150
     151    if (get_option(UBConfig::UB_PLUGIN_VERSION_KEY) != $current_version) {
    146152        UBConfig::set_options_if_not_exist();
    147         update_option(UBConfig::UB_PLUGIN_VERSION_KEY, UBConfig::UB_VERSION);
     153        update_option(UBConfig::UB_PLUGIN_VERSION_KEY, $current_version);
     154
     155        // When upgrading to 1.1.0, override all previous ub-page-server-domain values to new default
     156        // TODO: Remove this in subsequent plugin versions
     157        update_option(UBConfig::UB_PAGE_SERVER_DOMAIN_KEY, UBConfig::default_page_server_domain());
    148158    }
    149159
     
    208218        'Response Headers Forwarded',
    209219        function ($args) {
     220            $defaults = UBConfig::ub_option_defaults();
    210221            echo UBTemplate::render('settings_response_headers_forwarded', array(
    211222                'value' => get_option(UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY),
    212                 'default' => UBConfig::ub_option_defaults()[UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY]
     223                'default' => $defaults[UBConfig::UB_RESPONSE_HEADERS_FORWARDED_KEY]
    213224            ));
    214225        },
  • unbounce/trunk/readme.txt

    r2823212 r2953445  
    33Tags: Unbounce, AB testing, A/B testing, split testing, CRO, conversion optimization, wordpress landing page, wp landing pages, splash pages, landing pages, squeeze pages, lead gen, lead generation, email list, responsive landing pages, templates, inbound marketing, ppc, analytics
    44Requires at least: 4.1.5
    5 Tested up to: 6.0.2
    6 Stable tag: 1.0.49
     5Tested up to: 6.3
     6Stable tag: 1.1.0
    77Requires PHP: 7.2
    88License: GPLv2 or later
     
    104104== Changelog ==
    105105
     106= 1.1.0 =
     107* Changes the method used to communicate with Unbounce servers, which will improve the resilience of
     108  your pages to denial-of-service attacks
     109* Tested with WP 6.3
     110* **Important**: please upgrade to this version as soon as possible to benefit from these
     111  improvements. All older versions are now unsupported and will stop working in the near future.
     112
    106113= 1.0.49 =
    107114* Added setting to customize response headers forwarded from Unbounce
  • unbounce/trunk/templates/diagnostics.php

    r2823212 r2953445  
    77                      <li>Domain is not added in Unbounce account you are using to authorize. Make sure that the domain is present in a client you are the owner or administrator for.</li>
    88                      <li>Domain in Unbounce does not match WP configured domain (i.e. has, or does not have www.). The domain listed in Unbounce must match the WP domain exactly, so if it is configured to be www.domain.com, then that should be what is listed in the domain portion of your Unbounce account.</li>
    9                       <li>In order to connect with Unbounce, we need to validate the cert for wp.unbounce.com. Please make sure that your CA Cert file is up to date, as an out of date CA Cert file can cause the connection to fail</li>
     9                      <li>In order to connect with Unbounce, we need to validate the cert for proxy.unbouncepages.com. Please make sure that your CA Cert file is up to date, as an out of date CA Cert file can cause the connection to fail</li>
    1010                      </ul>
    1111                      For more troubleshooting information please read our <a href=\"https://documentation.unbounce.com/hc/en-us/articles/360000393623-Troubleshooting-WordPress-Plugin-Technical-Issues\" target=\"_blank\">Support Article</a>";
  • unbounce/trunk/templates/main_authorized_footer.php

    r2823212 r2953445  
    2222  Click here for troubleshooting and plugin diagnostics
    2323</a>
    24 <p class="ub-version">Unbounce Version 1.0.49</p>
     24<p class="ub-version">Unbounce Version 1.1.0</p>
  • unbounce/trunk/templates/main_unauthorized_footer.php

    r2823212 r2953445  
    55  Click here for troubleshooting and plugin diagnostics
    66</a>
    7 <p class="ub-version">Unbounce Version 1.0.49</p>
     7<p class="ub-version">Unbounce Version 1.1.0</p>
Note: See TracChangeset for help on using the changeset viewer.