0

I'm currently facing a little problem using .htaccess to redirect clients via "ephemeral" and unique links to different content (with different paths and extensions).

Let me explain this with some code I already got

.htaccess :

RewriteEngine on
RewriteRule (.+?)$ call.php?code=$1 [L,QSA]

call.php :

<?php
require_once("encryption.php");

if(isset($_GET['code']))
{
    // decryption of the code
    // the decrypted code is the content path
    $clearCode = DecryptFunction(htmlspecialchars($_GET['code']));
    
    if(strpos($clearCode, '.php') !== false)
    {
        include($clearCode);
    }
    else if(strpos($clearCode, '.jpeg') !== false)
    {
        $file_path_name = $clearCode;
        $ctype= 'image/jpeg';
        header('Content-Type: ' . $ctype);
        $handle = fopen($file_path_name, "rb");
        $contents = fread($handle, filesize($file_path_name));
        fclose($handle);
        echo $contents;
    }
    else if(strpos($clearCode, '.mp4') !== false)
    {
        $file_path_name = $clearCode;
        $ctype= 'video/mp4';
        header('Content-Type: ' . $ctype);
        $handle = fopen($file_path_name, "rb");
        $contents = fread($handle, filesize($file_path_name));
        fclose($handle);
        echo $contents;
    }
    
}
?>

In most situations this code works great but can cause some performance issues when big files are requested (like videos) and use larges amount of RAM on the server side, so I need a more efficient way for redirect clients.

The best would be to make those redirections directly from the .htaccess file but I don't know how to retrieve the decrypted path from there and I'm not sure it's possible. Then I could use apache environment variables to store temporarily the encrypted paths (as var name) and the decrypted one (as value) and retrieve them in the .htaccess, that could be something like this :

<?php
require_once("encryption.php");
$filePath = "some/clear/path/to/encrypt.extension";
$encryptedPath = EncryptFunction($filePath);
putenv("$encryptedPath=$filePath");
?>

<!DOCTYPE html>
<html>
<body>
 <img src = "<?php echo $encryptedPath;?>"/>
</body>
</html>
RewriteEngine on
RewriteRule (.+?)$ %{ENV:$1} [L,QSA]

Even there I'm not sure it can be very efficient and a looping script is needed on the server to dump the env variables regularly.

I have also looked about create a rewriting rules mapping file and edit it with php on the go but I don't really like this method.

So is it possible to call my php decryption function directly from the .htaccess file and redirect the client to the clear path? Or another method that I don't mentioned to do this?

I precise that I have the full control of the Apache server.

Thanks in advance for your answers :)

MadTek
  • 1
  • 2
  • If your issue is performance with large files, you can use [`readfile()`](https://www.php.net/manual/en/function.readfile.php) instead of `fopen` / `fread`. *"Note: readfile() will not present any memory issues, even when sending large files, on its own."* – Markus AO Oct 21 '20 at 13:26
  • Hello, I just tried it and it's working pretty fine but it still very long to load large files, I need this to work like a direct access and without charging the server by reading files. Thanks anyway for your answer :) – MadTek Oct 21 '20 at 13:51
  • And absolutely must mask the original filename? You can make PHP go faster than `readfile()` with a [`mod_xsendfile`](https://tn123.org/mod_xsendfile/) header ([overview](https://idiallo.com/blog/making-php-as-fast-as-nginx-or-apache)), however I don't know if it leaks the filename (don't have an installation handy to test). Also see, [Fastest Way to Serve a File Using PHP](https://stackoverflow.com/questions/3697748/fastest-way-to-serve-a-file-using-php) – Markus AO Oct 21 '20 at 14:48
  • In my case yes, it's a must have to hide the original filenames/paths of the content. All links have to be unique and one time usage. This method is fast as direct access but it share the content path in a header and can be read by the client... – MadTek Oct 21 '20 at 15:01

0 Answers0