woocommerceurlencodeurldecodeviber

Viber double encoding urls which contain Cyrillic symbols


Recently customers reported that they cannot open our links when we share them on Viber and only on iOS. They get redirected to 404 page. I started checking what is the issue and I noticed that for some reason Viber is double encoding the urls only on iOS.

Example url sent:

 example.com/%D0%BA%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B8/
End url for the user opening it on iOS: example.com/%25D0%25BA%25D0%25BE%25D0%25BD%25D1%2582%25D0%25B0%25D0%25BA%25D1%2582%25D0%25B8/

I noticed the added "25" before all the Cyrillic symbols. I've tested on Whatsapp, messenger and the links shared on iOS are working perfectly the issue is only on Viber for iOS. Same url opens correctly on Viber for android and Viber for Desktop. The metadata of the url is also correctly sent to the users on iOS.

So I ended up adding this to my functions.php file - using WooCommerce

add_action('init', 'normalize_request_uri_for_ios');

function normalize_request_uri_for_ios() {
    // Check if the user is on an iOS device
    if (wp_is_mobile() && strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') !== false) {
        // Decode the current URL
        $decoded_uri = urldecode($_SERVER['REQUEST_URI']);

        // Check if the URI contains the query parameter `redirected=1` to prevent loops
        if ($_SERVER['REQUEST_URI'] !== $decoded_uri && strpos($decoded_uri, '%') === false && !isset($_GET['redirected'])) {
            // Append the `redirected=1` parameter to prevent further redirection
            $new_uri = add_query_arg('redirected', '1', $decoded_uri);
            wp_safe_redirect($new_uri, 301);
            exit;
        }
    }
}

And it fixed my issue but I feel like this is a temporary fix for me and also I am not sure if this follows the best practice for handling such problem. I am also pretty sure that this was never an issue before as we usually share a lot of links to our customers and never had such issue.


Solution

  • I had the exact same issue. A slightly modified function worked for me:

    add_action('init', 'normalize_request_uri_for_ios');
    
    function normalize_request_uri_for_ios() {
        $user_agent = $_SERVER['HTTP_USER_AGENT'];
        
        // Check if the user is on an iPhone or iPad
        if (wp_is_mobile() && (strpos($user_agent, 'iPhone') !== false || strpos($user_agent, 'iPad') !== false)) {
            // Only process the URL if it contains '%25', indicating double encoding
            if (strpos($_SERVER['REQUEST_URI'], '%25') !== false) {
                // Decode the URL twice to fix the double-encoding issue
                $decoded_uri = urldecode(urldecode($_SERVER['REQUEST_URI']));
    
                // Prevent infinite redirects by checking if the URL is already decoded
                if ($_SERVER['REQUEST_URI'] !== $decoded_uri && !isset($_GET['redirected'])) {
                    // Add a query parameter to prevent repeated redirects
                    $new_uri = add_query_arg('redirected', '1', $decoded_uri);
                    wp_safe_redirect($new_uri, 301);
                    exit;
                }
            }
        }
    }
    

    But I think that ideally this should be fixed by the Viber team themselves.