Search code examples
phpcodeigniterasciiidnpunycode

punycode and .рф cyrillic domain redirect


I have a website with cyrillic domain name. There is an authorization lib which redirects the user to login page, but the url is somehow missformed.

The website is on CodeIgniter and the redirect function used is the standard redirect function of the codeigniter. I have modified a bit and it looks now like this

function redirect($uri = '', $method = 'location', $http_response_code = 302)
{
    if ( ! preg_match('#^https?://#ui', $uri))
    {
        $uri = site_url($uri);
    }


    //exit(idn_to_ascii($uri));
    switch($method)
    {
        case 'refresh'  : header("Refresh:0;url=http://".idn_to_ascii($uri));
            break;
        default         : header("Location:http://".idn_to_ascii($uri), TRUE, $http_response_code);
            break;
    }
    exit;
}

idn_to_ascii functions seems not rightly coding the UTF url string ...

Can anybody hint a solution?

Instead of

http://xn-------63dat7alb0aizbbjcoujt7j3a6e.xn--p1ai/auth/admin/

I get

xn-------63dat7alb0aizbbjcoujt7j3a6e.xn--/auth/login-foj4c

Any ideas ?


Solution

  • You should change your code a bit and use idn_to_ascii() only on domain part and not on the full url.

    instead of:

    switch($method)
        {
            case 'refresh'  : header("Refresh:0;url=http://".idn_to_ascii($uri));
                break;
            default         : header("Location:http://".idn_to_ascii($uri), TRUE, $http_response_code);
                break;
        }
    

    you should use:

    $pos = mb_strpos($uri,'/', null, 'UTF8');
    
    if ($pos === false) { // only domain, no slash here
        $uri = idn_to_ascii($uri);
    }
    else { // changes only for domain part, rest left unchanged
        $uri = idn_to_ascii(mb_substr($uri,0,$pos, 'UTF-8')).mb_substr($uri,$pos,null, 'UTF-8');
    }
    
    
    switch($method)
        {
            case 'refresh'  : header("Refresh:0;url=http://".$uri);
                break;
            default         : header("Location:http://".$uri, TRUE, $http_response_code);
                break;
        }
    

    EDIT

    Test code just for generating URL:

    <?php
    
    $uri = 'помощь-от-сглаза-и-порчи.рф/auth/admin/';
    
    $pos = mb_strpos($uri,'/', null, 'UTF8');
    
    if ($pos === false) {
        $uri = idn_to_ascii($uri);
    }
    else {
        $uri = idn_to_ascii(mb_substr($uri,0,$pos, 'UTF-8')).mb_substr($uri,$pos,null, 'UTF-8');
    }
    
    echo $uri."<br />";
    

    Output for this is: xn-------63dat7alb0aizbbjcoujt7j3a6e.xn--p1ai/auth/admin/ as expected I think - when I copy this text into browser I get redirected again to http://помощь-от-сглаза-и-порчи.рф/auth/admin/