A follow-up to my download-all-files-as-a-zip-file post

A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 03:29:38 von techusky

I made a script that successfully creates a .zip file of all the files
in a directory on my web server, but now what I haven't figured out
how to do is how to have it automatically deleted when the user
successfully downloads it, as otherwise my server would eventually get
clogged up with all these zip files.

Any help/suggestions?

Thanks

Re: A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 03:52:54 von luiheidsgoeroe

On Sun, 05 Aug 2007 03:29:38 +0200, wrote:

> I made a script that successfully creates a .zip file of all the files
> in a directory on my web server, but now what I haven't figured out
> how to do is how to have it automatically deleted when the user
> successfully downloads it, as otherwise my server would eventually get
> clogged up with all these zip files.
>
> Any help/suggestions?

If you're serving it using PHP itself, a construct _might_ be possible by
using ignore_user_abort() and checking the connection_status() at the end
(after all data is sent), and unlink the file if there's been no abortion.
However, ths smaller the file, the less trustworthy it becomes (Think of
the UA: you ask to download, you abort, but if it's allready in, the
connection was succesfull. Now try to download it again, and it's
gone...). If all is reproducable (i.e. the original files/data remains,
only the zip files need to be cleaned up) the only problem is wasted
resources. If you're deleting data you can't get again it's not wise to
delete anything unless you're really, really sure.

This has been discussed in this group thoroughly a few months ago, try to
search the archives. I think the ignore_user_abort/unlink functions are
mentioned in it, so it's a place to start searching.

From the top of my head, I think the final solution was it's better to ask
for a user confirmation, and temporary clean old files up using a cron job.
--
Rik Wasmus

Re: A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 05:04:57 von Matt Madrid

techusky@gmail.com wrote:
> I made a script that successfully creates a .zip file of all the files
> in a directory on my web server, but now what I haven't figured out
> how to do is how to have it automatically deleted when the user
> successfully downloads it, as otherwise my server would eventually get
> clogged up with all these zip files.
>
> Any help/suggestions?
>
> Thanks
>
I'd probably just create a cron job that deletes any zip files older than
a day. That's the simplest way I can think of. Of course, depending on the
amount of disk space you have available, and how trustworthy your users are,
this could open you up to a DOS attack of sorts. A person could keep clicking
on the download link (or automate it) and possibly fill up your whole disk in
a day.

Re: A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 05:31:26 von techusky

On Aug 4, 8:04 pm, Matt Madrid wrote:
> techu...@gmail.com wrote:
> > I made a script that successfully creates a .zip file of all the files
> > in a directory on my web server, but now what I haven't figured out
> > how to do is how to have it automatically deleted when the user
> > successfully downloads it, as otherwise my server would eventually get
> > clogged up with all these zip files.
>
> > Any help/suggestions?
>
> > Thanks
>
> I'd probably just create a cron job that deletes any zip files older than
> a day. That's the simplest way I can think of. Of course, depending on the
> amount of disk space you have available, and how trustworthy your users are,
> this could open you up to a DOS attack of sorts. A person could keep clicking
> on the download link (or automate it) and possibly fill up your whole disk in
> a day.

I had a thought during dinner, but I'm not sure if this would
*actually* work or not:

Could I initiate a session when a user navigates to a folder, and when
they leave that particular folder destroy the session which I could
then trigger using a simple if-statement to delete the .zip file?

Re: A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 10:23:08 von Toby A Inkster

Matt Madrid wrote:

> I'd probably just create a cron job that deletes any zip files older than
> a day. That's the simplest way I can think of. Of course, depending on the
> amount of disk space you have available, and how trustworthy your users are,
> this could open you up to a DOS attack of sorts. A person could keep clicking
> on the download link (or automate it) and possibly fill up your whole disk in
> a day.

A solution which would solve both the "when to delete" question, and the
possibility of DOS attacks would be to simply *keep* all the ZIP files as a
*cache*. This should actually *reduce* the load on the server.

Sketch of how it would work, assuming $X is the place where you keep these
ZIP files you've made...

1. User requests a ZIPped directory. Call this directory $D.

2. You scan through each file in $D to find the "last modified"
date of the *newest* file in $D.

3. Call the timestamp of that last modification $T.

4. Does there exist a file "$X/$D.zip"? If not, go to step 9.

5. Is the last-modified date of "$X/$D.zip" older than $T?
If so, go to step 8.

6. Serve up "$X/$D.zip".

7. Exit.

8. Delete "$X/$D.zip".

9. Zip up directory $D and call it "$X/$D.zip".

10. Use the UNIX "touch" command to change the last-modified
and created dates of "$X/$D.zip" to $T.

11. Go to step 6.

--
Toby A Inkster BSc (Hons) ARCS
[Geek of HTML/SQL/Perl/PHP/Python/Apache/Linux]
[OS: Linux 2.6.12-12mdksmp, up 45 days, 11:47.]

Command Line Interfaces, Again
http://tobyinkster.co.uk/blog/2007/08/02/command-line-again/

Re: A follow-up to my download-all-files-as-a-zip-file post

am 05.08.2007 11:02:31 von Matt Madrid

techusky@gmail.com wrote:
> On Aug 4, 8:04 pm, Matt Madrid wrote:
>> techu...@gmail.com wrote:
>>> I made a script that successfully creates a .zip file of all the files
>>> in a directory on my web server, but now what I haven't figured out
>>> how to do is how to have it automatically deleted when the user
>>> successfully downloads it, as otherwise my server would eventually get
>>> clogged up with all these zip files.
>>> Any help/suggestions?
>>> Thanks
>> I'd probably just create a cron job that deletes any zip files older than
>> a day. That's the simplest way I can think of. Of course, depending on the
>> amount of disk space you have available, and how trustworthy your users are,
>> this could open you up to a DOS attack of sorts. A person could keep clicking
>> on the download link (or automate it) and possibly fill up your whole disk in
>> a day.
>
> I had a thought during dinner, but I'm not sure if this would
> *actually* work or not:
>
> Could I initiate a session when a user navigates to a folder, and when
> they leave that particular folder destroy the session which I could
> then trigger using a simple if-statement to delete the .zip file?
>

Well, that could work. I guess you mean something like this:

if (get_cwd() != $_SESSION['zip_directory']) {
delete_zip_file($_SESSION['zip_file']);
unset($_SESSION['zip_directory']);
unset($_SESSION['zip_file']);
}

Well, what happens if the user opens another browser tab while the download
is in progress. Then the cwd might be different, and the zip file would be
deleted in the middle of the transfer. Actually, there would probably be a
"file in use" error, so the file would never be deleted.

How are you doing the download? A direct link to the file, or streaming it
from the php script? I mentioned before that you could use header() and
file_get_contents to send the file. That might be your best bet here, except
that I would use passthru() instead.

You could then create a class and use its destructor method to delete the file.

Something like this (quick code.. but tested):

---------------

set_time_limit(0);
class zipit {
public $zipfile;
public $filename;
public function zip($directory) {
$tmp_file = "/tmp/zipfile".md5(microtime()).".zip";
$this->filename = basename($directory) . ".zip";
exec("zip -rj $tmp_file $directory",$output,$retval);
if (!$retval) {
$this->zipfile = $tmp_file;
return true;
}
else {
return false;
}
}
public function download() {
if (!is_readable($this->zipfile)) {
die("Something went wrong");
}
header("Content-type: application/zip");
header('Content-Disposition: file; filename="' . $this->filename);
passthru("cat ". $this->zipfile);
}
function __destruct() {
// delete the temporary zip file
unlink($this->zipfile);
}
}

$z = new zipit();

if ($z->zip("/tmp/nothing")) {
$z->download();
}

---------------

Hope this helps..

Matt M.