Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update URL parsing logic (again). #1996

Merged
merged 1 commit into from
Apr 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions flixel/system/FlxBasePreloader.hx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class FlxBasePreloader extends NMEPreloader
/**
* Add this string to allowedURLs array if you want to be able to test game with enabled site-locking on local machine
*/
public static inline var LOCAL:String = #if flash "local" #else "localhost" #end;
public static inline var LOCAL:String = "localhost";

/**
* Change this if you want the flixel logo to show for more or less time. Default value is 0 seconds (no delay).
Expand Down Expand Up @@ -250,21 +250,15 @@ class FlxBasePreloader extends NMEPreloader
private function isHostUrlAllowed():Bool
{
if (allowedURLs.length == 0)
{
return true;
}

var homeDomain:String = FlxStringUtil.getDomain(#if flash loaderInfo.loaderURL #elseif js js.Browser.location.href #end);

var homeURL:String = #if flash loaderInfo.loaderURL #elseif js js.Browser.location.href #end;
var homeDomain:String = FlxStringUtil.getDomain(homeURL);
for (allowedURL in allowedURLs)
{
if (FlxStringUtil.getDomain(allowedURL) == homeDomain)
{
var allowedDomain = FlxStringUtil.getDomain(allowedURL);
if (allowedDomain == homeDomain)
return true;
}
else if (allowedURL == LOCAL && homeDomain == LOCAL)
{
return true;
}
}
return false;
}
Expand Down
38 changes: 35 additions & 3 deletions flixel/util/FlxStringUtil.hx
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,46 @@ class FlxStringUtil
}
return s;
}

/**
* Returns the host from the specified URL.
* The host is one of three parts that comprise the authority. (User and port are the other two parts.)
* For example, the host for "ftp://anonymous@ftp.domain.test:990/" is "ftp.domain.test".
*
* @return The host from the URL; or the empty string ("") upon failure.
*/
public static function getHost(url:String):String
{
var hostFromURL:EReg = ~/^[a-z][a-z0-9+\-.]*:\/\/(?:[a-z0-9\-._~%!$&'()*+,;=]+@)?([a-z0-9\-._~%]+|\[[a-f0-9:.]+\])?(?::[0-9]+)?/i;
if (hostFromURL.match(url))
{
var host = hostFromURL.matched(1);
return (host != null) ? host.urlDecode().toLowerCase() : "";
}

return "";
}

/**
* Returns the domain of a URL.
* Returns the domain from the specified URL.
* The domain, in this case, refers specifically to the first and second levels only.
* For example, the domain for "api.haxe.org" is "haxe.org".
*
* @return The domain from the URL; or the empty string ("") upon failure.
*/
public static function getDomain(url:String):String
{
var regex:EReg = ~/(?:[a-z0-9.+-]+:\/\/)(?:[a-z0-9-]+\.)*([a-z0-9-]+\.[a-z0-9-]+)/i;
return regex.match(url) ? regex.matched(1).toLowerCase() : "local";
var host:String = getHost(url);

var isLocalhostOrIPaddress:EReg = ~/^(localhost|[0-9.]+|\[[a-f0-9:.]+\])$/i;
var domainFromHost:EReg = ~/^(?:[a-z0-9\-]+\.)*([a-z0-9\-]+\.[a-z0-9\-]+)$/i;
if (!isLocalhostOrIPaddress.match(host) && domainFromHost.match(host))
{
var domain = domainFromHost.matched(1);
return (domain != null) ? domain.toLowerCase() : "";
}

return "";
}

/**
Expand Down
75 changes: 56 additions & 19 deletions tests/unit/src/flixel/util/FlxStringUtilTest.hx
Original file line number Diff line number Diff line change
Expand Up @@ -100,29 +100,30 @@ class FlxStringUtilTest
Assert.isFalse(FlxStringUtil.isNullOrEmpty("Hello World"));
}

@Test
function testGetDomainNonLocal()
/**
* Returns an array of valid URLs for testing.
*
* @param host The host to insert into the generated URLs.
*/
function generateTestURLs(host:String):Array<String>
{
var domain = "xn--eckwd4c7c.test";
var urls = new Array<String>();

// Examples of valid URI components.
var schemes = ["http", "https", "fake.but-valid+scheme"];
var hosts = ['$domain', 'www.$domain', 'aaa.bbb.ccc.$domain'];
var authorities = ['$host', 'user@$host', '$host:1234'];
var paths = ["", "/", "/index.html", "/path/to/file.extension?query=42"];

for (scheme in schemes) for (host in hosts) for (path in paths)
{
var uri = mixedCase('$scheme://$host$path');
Assert.areEqual(domain, FlxStringUtil.getDomain(uri));
}
for (authority in authorities) for (path in paths)
urls.push(mixedCase('fake.but-valid+scheme://$authority$path'));

return urls;
}

/**
* Returns a string with a mixture of upper and lower case characters.
*/
function mixedCase(string:String):String
{
var result = "", upper = false;
var result = "", upper = (string.length % 2 == 0);
for (i in 0...string.length)
{
var char = string.charAt(i);
Expand All @@ -131,22 +132,58 @@ class FlxStringUtilTest
return result;
}

@Test
function testGetDomainLocal()
/**
* Returns an array of local file paths for testing.
* Includes Unix-style and Windows-style paths as well as a file:// URL.
*/
function generateLocalPaths():Array<String>
{
// Examples of some Unix-style and Windows-style local file paths.
var paths = [
return [
"/root/folder/file.extension",
"./folder/file.extension",
"~/.extension",
"D:\\folder\\file.extension",
"D:\\folder\\file.extension:alternate_stream_name",
"D:file.extension",
"\\\\server\\folder\\file.extension",
"\\\\?\\D:\\folder\\file.extension"
"\\\\?\\D:\\folder\\file.extension",
"file:///D:/folder/file.extension"
];
}

@Test
function testGetHostValidURLs()
{
var hosts = ["123.45.67.89", "[1234:5678:9abc:def0::1]", "asdf.xn--eckwd4c7c.test"];
for (host in hosts) for (url in generateTestURLs(host))
Assert.areEqual(host, FlxStringUtil.getHost(url));

Assert.areEqual("abc.test", FlxStringUtil.getHost("http://%41%42%43.test"));
}

@Test
function testGetHostInvalidURLs()
{
for (path in generateLocalPaths())
Assert.areEqual("", FlxStringUtil.getHost(path));
}

@Test
function testGetDomainNonLocal()
{
var domain = "xn--eckwd4c7c.test";
for (url in generateTestURLs('extra.data.$domain'))
Assert.areEqual(domain, FlxStringUtil.getDomain(url));
}

@Test
function testGetDomainLocal()
{
var hosts = ["localhost", "123.45.67.89", "[1234:5678:9abc:def0::1]"];
for (host in hosts) for (url in generateTestURLs(host))
Assert.areEqual("", FlxStringUtil.getDomain(url));

for (path in paths)
Assert.areEqual("local", FlxStringUtil.getDomain(path));
for (path in generateLocalPaths())
Assert.areEqual("", FlxStringUtil.getDomain(path));
}
}