0

I am working on a script that calls a third party api, which needs a valid server hostname. Any of these format should be allowed, for example:

  • server.domain.com
  • server1.domain.com
  • something.domain.com
  • 123456x.domain.tld

etc...

So, I have put together the following script to sanitize the server's hostname (in the event user inputs an invalid entry):

$server_hostname = 'test';

if (IsValidHostname($server_hostname))
{
    switch (substr_count($server_hostname, '.'))
    {
        case 1:
            $server_hostname = 'server.'. $server_hostname;
            break;

        case 0:
            $server_hostname = 'server'. time() .'.default-domain.com';
            break;
    }
}
else
{
    $server_hostname = 'server'. time() .'.default-domain.com';
}

var_dump($server_hostname);

function IsValidHostname($hostname)
{
    // Src: http://stackoverflow.com/a/4694816
    return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $hostname)
            && preg_match("/^.{1,253}$/", $hostname)
            && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $hostname)
    );
}

The script appears to work. If an invalid hostname is supplied, it auto-generates a random one. Here are few test cases:

test                -> server1451385708.default-domain.com
test.com            -> server.test.com
123-test.com        -> server.123-test.com
adam.test.com       -> adam.test.com
e-v-e.test.com      -> e-v-e.test.com
server12.test.co.uk -> server12.test.co.uk

However, I am not sure this is quite perfect yet. Here's a test that failed:

test.co.uk -> test.co.uk

I would prefer the outcome to be the following, when tld has 2 parts (e.g. co.uk):

test.co.uk -> server.test.co.uk

Any ideas on how I can achieve this?

Latheesan
  • 23,247
  • 32
  • 107
  • 201

2 Answers2

0

Like this, this just covers the case that there are two ".":

if (IsValidHostname($server_hostname))
    {
        switch (substr_count($server_hostname, '.'))
        {
            case 1:
            case 2:
                $server_hostname = 'server.'. $server_hostname;
                break;

            case 0:
                $server_hostname = 'server'. time() .'.default-domain.com';
                break;
        }
    }
    else
    {
        $server_hostname = 'server'. time() .'.default-domain.com';
    }

or like this, which adds the info regardless of the number of ".":

if (IsValidHostname($server_hostname))
    {
        switch (substr_count($server_hostname, '.'))
        {
            case 0:
                $server_hostname = 'server'. time() .'.default-domain.com';
                break;

            default:
                $server_hostname = 'server.'. $server_hostname;
                break;
        }
    }
    else
    {
        $server_hostname = 'server'. time() .'.default-domain.com';
    }
Philipp Palmtag
  • 1,310
  • 2
  • 16
  • 18
0

This is what I have settled on for now, let me know if there is a better way of doing it:

// Sanitize server's hostname
$serverHostname = strtolower(trim($server['hostname']));
if ($this->IsValidHostname($serverHostname)) {
    switch (substr_count($serverHostname, '.')) {
        case 1:
        case 2:
            if (substr($serverHostname, 0, 7) !== 'server.')
                $serverHostname = uniqid() .'.'. $serverHostname;
            break;
        case 0:
            $serverHostname = uniqid() .'.default-domain.com';
            break;
    }
} else {
    $serverHostname = uniqid() .'.default-domain.com';
}
Latheesan
  • 23,247
  • 32
  • 107
  • 201