Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay unlink after Header

Tags:

php

unlink

I'm trying to create a secure document retrieval system for logged in users.

First I check if the user is logged in. If they are I progress to copy the file from the protected directory on the server to the web accessible space within the users current directory.

I then redirect them to the URL the file is now within. Tell the code to sleep for 10 seconds to allow slow connections time to download the file and then to delete it so the link is no longer usable by others.

My problem is that after the header the sleep function is not working. I tried removing the if statement and this made the script sleep for 10 seconds and then unlink the file before redirecting the user so the link as already broken.

I'm struggling to find a way to make the script sleep for 10 seconds and still execute the code AFTER the redirect has happened.

    <?php
if(!isset($_SESSION['id'])){
header("location:../../../");
}
else {
    echo copy('C:\directorypath\test.xls','test.xls');
    if(header("location:../docs/test.xls")){
    sleep("10");
    unlink("test.xls");
    }
}
    ?>
like image 514
James Avatar asked Jun 23 '26 23:06

James


1 Answers

What you are trying to do is in practice impossible to do with PHP, because PHP is single threaded and executed from start-to-finish for each request. This means that the header redirect is not done until all the code in your script is completed. This means that the script will first wait, then delete the file, then attempt to redirect to a non-exiting file.

Instead I purpose another approach; using and storing a unique hash that is usable only once.

Check if the user is logged in. If he or she is logged in, generate a unique hash and insert it in the database e.g. INSERT INTO hashes (hash, used) VALUES ($myUniqueHash, 0). Then redirect the user to a PHP-file with the hash in the request query, e.g.

header("Location: serve_file.php?hash=$myUniqueHash");

This file will check the value of $_GET['hash'] against the table that contains the hashes, and check if the value of used is 0. If this is the case it will update the used column to 1 and serve the file as a proxy. If the hash is not found, or if the value of the used column is not 0 it will return an error.

This way we can serve a (secret) file only once for logged in users.

like image 175
OptimusCrime Avatar answered Jun 29 '26 01:06

OptimusCrime