- Patch #777830 by Wim Leers: file_create_url() does not support protocol-relative nor root-relative file URLs.
parent
8b08712449
commit
a495441521
|
@ -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
|
||||
|
|
|
@ -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 URL for a shipped file.'));
|
||||
$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 URL for a shipped file.'));
|
||||
$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('/' . 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('/' . 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 URL for a created file.'));
|
||||
$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('/' . base_path() . '/' . file_directory_path() . '/' . $file->filename, $url, t('Correctly generated a protocol-relative URL for a created file.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
// Test alteration of file URLs to use a CDN.
|
||||
elseif ($alter_mode == 'cdn') {
|
||||
$cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png');
|
||||
|
||||
$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');
|
||||
|
||||
// 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);
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue