Mobile app version of vmapp.org
Login or Join
Hamm4606531

: Make .URL shortcuts into functional links within a Directory Listing I use a lot of directory listing on my website and want to make .URL shortcut files into functional links. These .URL shortcuts

@Hamm4606531

Posted in: #Apache #DirectoryListing #Htaccess #Links

I use a lot of directory listing on my website and want to make .URL shortcut files into functional links. These .URL shortcuts were made by dragging the websites' icons from my Firefox URL bar to my Windows desktop.

The problem: Clicking a .URL item from a browser directory listing only displays the file's parameters (including the URL, see below) but does not load the website.

How can we make clicking a .URL item actually load the website?

I've searched every keyword combination I could think of but found no answers. The closest was a similar (but unanswered) question on StackOverflow: URL Shortcut in Web Directory

A further limitation is that I have shared Linux hosting from GoDaddy and thus don't have access to all the server setting "bells and whistles".



.URL Files

The Windows internet shortcut .URL file is an INI file of the following form, which contains the target URL in the URL key.

[InternetShortcut]
URL=https://eclipse2017.nasa.gov/sites/default/files/interactive_map/index.html
IDList=
HotKey=0
IconFile=C:UsersSunnyAppDataLocalMozillaFirefoxProfiles ... ==.ico
IconIndex=0




Live Example

In the directory: SoSaysSunny.com/eclipse_2017-08-21/
... I'd like the .URL items to be functional links.

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Hamm4606531

1 Comments

Sorted by latest first Latest Oldest Best

 

@Ogunnowo487

I'm not aware of an Apache specific way to do this "automagically".

However, it's reasonably trivial to script this yourself. You can use the Apache module "mod_rewrite" (in .htaccess) to rewrite such requests to a PHP script that parses out the target URL to issue the redirect.

For example, in your root .htaccess file, include the following (mod_rewrite directives):

Options +Indexes

RewriteEngine On
RewriteBase /

# Rewrite requests for ".url" files to our PHP script
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ..url$ process-url-shortcut.php [NS,NC,E=URL_FILE:%{REQUEST_FILENAME},L]


UPDATE: The NS flag is required if this is used together with Apache's generated directory listings - particularly if you are specifying custom icons (AddIcon) and descriptions (AddDescription) with Apache's FancyIndexing option (as above). This is to prevent the directive being processed during internal subrequests. See my answer to this follow up question for more information.



This rewrites all requests for URLs that end .url or .URL (not case-sensitive) that also map to existing files, to the PHP file /process-url-shortcut.php (in the document root) which ultimately handles the request. This also sets an environment variable, URL_FILE, that contains the full filesystem path of the file being requested. (Note that this becomes REDIRECT_URL_FILE after the internal rewrite - see the additional note below.)

Addtional... Note that the PHP script could exist anywhere, it doesn't need to go in the document root. (In fact, it would actually be preferable if this script was in a subdirectory elsewhere on the file system. The script is already passed an absolute file system path, so it doesn't matter where the script itself is located.) To locate the script somewhere else, you just need to update the RewriteRule substitution (ie. process-url-shortcut.php - the target URL). For example, if the script was located in a /scripts subdirectory off the document root, then you could change process-url-shortcut.php to read /scripts/process-url-shortcut.php instead - the slash prefix on the URL is optional in this example, because we have already specified this in the RewriteBase directive. Note that you must not specify an absolute URL here (ie. with a scheme + hostname) since this will implicitly trigger an external redirect, as opposed to an internal rewrite, which is not what we want.

The environment variable is used later by our PHP script. We could calculate the filename using PHP, however, this would take a few lines of code to parse the filename from the requested URL. It seemed easier and possibly more reliable to grab this with Apache's mod_rewrite instead, which already knows the absolute filename the original request mapped to (ie. our URL file). This also provides an easy way to block direct requests to our PHP script; if the environment variable is not set then the script is being requested directly, so block it. Two birds; one stone.

The PHP script /process-url-shortcut.php then handles the request:

<?php
// Check for environment variable that contains the URL file being requested
// - This is set during the internal rewrite in .htaccess
$urlFile = getenv('REDIRECT_URL_FILE');
if ($urlFile) {

# Read the contents of the URL file
$urlFileData = file_get_contents($urlFile);
if ($urlFileData) {

# Extract just the target URL from the file
if (preg_match('/url=(.+)/i',$urlFileData,$urlMatch)) {

# If found a target URL in the file then redirect...
if (isset($urlMatch[1])) {
header('Location: '.$urlMatch[1],true,302);
exit;
}

}

}

}

// If got this far then script was accessed directly or something went wrong...
http_response_code(404);
?>
<h1>404 Not Found</h1>


This looks for the first url=<something> in the requested file (not case-sensitive), using a regex. And extracts <something> to be used in the HTTP redirect.

Note that this contains only the bare minimum validation. You could check that the target URL looks like a URL, limit the target URLs to certain domains, restrict the directories that get parsed for .url files. etc. etc.



I was going to use PHP's parse_ini_file() to extract the URL key value, however, the example "INI file" given in the question does not appear to conform to the specification PHP is expecting:


Warning: syntax error, unexpected '=' in ... on line 5


Which appears to relate to the == that appears later on the IconFile line.



Additional Notes...


The php "REDIRECT_URL_FILE" doesn't match the .htaccess "E=URL_FILE"


Yes, that is correct. This is indeed a bit confusing (especially if you are not familiar with how the rewrite engine works). Whilst we set the environment variable URL_FILE at the time of the URL rewrite, Apache renames this to REDIRECT_URL_FILE after the rewrite occurs. In fact, all environment variables that existed prior to the rewrite are prefixed with REDIRECT_ after the rewrite (that is, after this pass through the rewrite process, not literally just after that directive).


Also: I'm trying to make web links (e.g. nasa.gov), not "full filesystem path" links, if that makes a difference.


The "full filesystem path" that I refer to in my answer is just the "filesystem path" of the actual file being requested, ie. the .URL file you have saved to that directory. The "full filesystem path" is simply required so that the PHP script is able to open and read this file. Yes, this ultimately creates "web links" to the URL that is specified within the shortcut file.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme