diff options
-rw-r--r-- | includes/file.inc | 18 | ||||
-rw-r--r-- | modules/simpletest/tests/file.test | 43 | ||||
-rw-r--r-- | modules/simpletest/tests/file_test.module | 111 |
3 files changed, 134 insertions, 38 deletions
diff --git a/includes/file.inc b/includes/file.inc index da47b3590..cb01ae24f 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -343,9 +343,21 @@ function file_create_url($uri) { $scheme = file_uri_scheme($uri); if (!$scheme) { - // If this is not a properly formatted stream, then it is a shipped file. - // Therefor, return the URI with the base URL prepended. - return $GLOBALS['base_url'] . '/' . $uri; + // Allow for: + // - root-relative URIs (e.g. /foo.jpg in http://example.com/foo.jpg) + // - protocol-relative URIs (e.g. //bar.jpg, which is expanded to + // http://example.com/bar.jpg by the browser when viewing a page over + // HTTP and to https://example.com/bar.jpg when viewing a HTTPS page) + // Both types of relative URIs are characterized by a leading slash, hence + // we can use a single check. + if (drupal_substr($uri, 0, 1) == '/') { + return $uri; + } + else { + // If this is not a properly formatted stream, then it is a shipped file. + // Therefor, return the URI with the base URL prepended. + return $GLOBALS['base_url'] . '/' . $uri; + } } elseif ($scheme == 'http' || $scheme == 'https') { // Check for http so that we don't have to implement getExternalUrl() for diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test index 939430d72..b8afcd167 100644 --- a/modules/simpletest/tests/file.test +++ b/modules/simpletest/tests/file.test @@ -2022,7 +2022,6 @@ class FileURLRewritingTest extends FileTestCase { function setUp() { parent::setUp('file_test'); - variable_set('file_test_hook_file_url_alter', TRUE); } /** @@ -2031,12 +2030,33 @@ class FileURLRewritingTest extends FileTestCase { function testShippedFileURL() { // Test generating an URL to a shipped file (i.e. a file that is part of // Drupal core, a module or a theme, for example a JavaScript file). + + // Test alteration of file URLs to use a CDN. + variable_set('file_test_hook_file_url_alter', 'cdn'); + $filepath = 'misc/jquery.js'; + $url = file_create_url($filepath); + $this->assertEqual(FILE_URL_TEST_CDN_1 . '/' . $filepath, $url, t('Correctly generated a CDN URL for a shipped file.')); + $filepath = 'misc/favicon.ico'; + $url = file_create_url($filepath); + $this->assertEqual(FILE_URL_TEST_CDN_2 . '/' . $filepath, $url, t('Correctly generated a CDN URL for a shipped file.')); + + // Test alteration of file URLs to use root-relative URLs. + variable_set('file_test_hook_file_url_alter', 'root-relative'); + $filepath = 'misc/jquery.js'; + $url = file_create_url($filepath); + $this->assertEqual(base_path() . '/' . $filepath, $url, t('Correctly generated a root-relative URL for a shipped file.')); + $filepath = 'misc/favicon.ico'; + $url = file_create_url($filepath); + $this->assertEqual(base_path() . '/' . $filepath, $url, t('Correctly generated a root-relative URL for a shipped file.')); + + // Test alteration of file URLs to use protocol-relative URLs. + variable_set('file_test_hook_file_url_alter', 'protocol-relative'); $filepath = 'misc/jquery.js'; $url = file_create_url($filepath); - $this->assertEqual(FILE_URL_TEST_CDN_1 . '/' . $filepath, $url, t('Correctly generated a URL for a shipped file.')); + $this->assertEqual('/' . base_path() . '/' . $filepath, $url, t('Correctly generated a protocol-relative URL for a shipped file.')); $filepath = 'misc/favicon.ico'; $url = file_create_url($filepath); - $this->assertEqual(FILE_URL_TEST_CDN_2 . '/' . $filepath, $url, t('Correctly generated a URL for a shipped file.')); + $this->assertEqual('/' . base_path() . '/' . $filepath, $url, t('Correctly generated a protocol-relative URL for a shipped file.')); } /** @@ -2044,9 +2064,24 @@ class FileURLRewritingTest extends FileTestCase { */ function testPublicCreatedFileURL() { // Test generating an URL to a created file. + + // Test alteration of file URLs to use a CDN. + variable_set('file_test_hook_file_url_alter', 'cdn'); + $file = $this->createFile(); + $url = file_create_url($file->uri); + $this->assertEqual(FILE_URL_TEST_CDN_2 . '/' . file_directory_path() . '/' . $file->filename, $url, t('Correctly generated a CDN URL for a created file.')); + + // Test alteration of file URLs to use root-relative URLs. + variable_set('file_test_hook_file_url_alter', 'root-relative'); + $file = $this->createFile(); + $url = file_create_url($file->uri); + $this->assertEqual(base_path() . '/' . file_directory_path() . '/' . $file->filename, $url, t('Correctly generated a root-relative URL for a created file.')); + + // Test alteration of file URLs to use a protocol-relative URLs. + variable_set('file_test_hook_file_url_alter', 'protocol-relative'); $file = $this->createFile(); $url = file_create_url($file->uri); - $this->assertEqual(FILE_URL_TEST_CDN_2 . '/' . file_directory_path() . '/' . $file->filename, $url, t('Correctly generated a URL for a created file.')); + $this->assertEqual('/' . base_path() . '/' . file_directory_path() . '/' . $file->filename, $url, t('Correctly generated a protocol-relative URL for a created file.')); } } diff --git a/modules/simpletest/tests/file_test.module b/modules/simpletest/tests/file_test.module index b14dd6ef4..6d4d1f8c5 100644 --- a/modules/simpletest/tests/file_test.module +++ b/modules/simpletest/tests/file_test.module @@ -286,41 +286,90 @@ function file_test_file_delete($file) { function file_test_file_url_alter(&$uri) { // Only run this hook when this variable is set. Otherwise, we'd have to add // another hidden test module just for this hook. - if (!variable_get('file_test_hook_file_url_alter', FALSE)) { + $alter_mode = variable_get('file_test_hook_file_url_alter', FALSE); + if (!$alter_mode) { return; } - - $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png'); - - // Most CDNs don't support private file transfers without a lot of hassle, - // so don't support this in the common case. - $schemes = array('public'); - - $scheme = file_uri_scheme($uri); - - // Only serve shipped files and public created files from the CDN. - if (!$scheme || in_array($scheme, $schemes)) { - // Shipped files. - if (!$scheme) { - $path = $uri; - } - // Public created files. - else { - $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme); - $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri); + // Test alteration of file URLs to use a CDN. + elseif ($alter_mode == 'cdn') { + $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png'); + + // Most CDNs don't support private file transfers without a lot of hassle, + // so don't support this in the common case. + $schemes = array('public'); + + $scheme = file_uri_scheme($uri); + + // Only serve shipped files and public created files from the CDN. + if (!$scheme || in_array($scheme, $schemes)) { + // Shipped files. + if (!$scheme) { + $path = $uri; + } + // Public created files. + else { + $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme); + $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri); + } + + // Clean up Windows paths. + $path = str_replace('\\', '/', $path); + + // Serve files with one of the CDN extensions from CDN 1, all others from + // CDN 2. + $pathinfo = pathinfo($path); + if (array_key_exists('extension', $pathinfo) && in_array($pathinfo['extension'], $cdn_extensions)) { + $uri = FILE_URL_TEST_CDN_1 . '/' . $path; + } + else { + $uri = FILE_URL_TEST_CDN_2 . '/' . $path; + } } - - // Clean up Windows paths. - $path = str_replace('\\', '/', $path); - - // Serve files with one of the CDN extensions from CDN 1, all others from - // CDN 2. - $pathinfo = pathinfo($path); - if (array_key_exists('extension', $pathinfo) && in_array($pathinfo['extension'], $cdn_extensions)) { - $uri = FILE_URL_TEST_CDN_1 . '/' . $path; + } + // Test alteration of file URLs to use root-relative URLs. + elseif ($alter_mode == 'root-relative') { + // Only serve shipped files and public created files with root-relative + // URLs. + $scheme = file_uri_scheme($uri); + if (!$scheme || $scheme == 'public') { + // Shipped files. + if (!$scheme) { + $path = $uri; + } + // Public created files. + else { + $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme); + $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri); + } + + // Clean up Windows paths. + $path = str_replace('\\', '/', $path); + + // Generate a root-relative URL. + $uri = base_path() . '/' . $path; } - else { - $uri = FILE_URL_TEST_CDN_2 . '/' . $path; + } + // Test alteration of file URLs to use protocol-relative URLs. + elseif ($alter_mode == 'protocol-relative') { + // Only serve shipped files and public created files with protocol-relative + // URLs. + $scheme = file_uri_scheme($uri); + if (!$scheme || $scheme == 'public') { + // Shipped files. + if (!$scheme) { + $path = $uri; + } + // Public created files. + else { + $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme); + $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri); + } + + // Clean up Windows paths. + $path = str_replace('\\', '/', $path); + + // Generate a protocol-relative URL. + $uri = '/' . base_path() . '/' . $path; } } } |