Clean up tar process handling; make stdout non-blocking.

This commit is contained in:
Aaron van Geffen 2020-03-11 12:13:04 +01:00
parent 2bb29d7224
commit 5a51778a6a
1 changed files with 19 additions and 8 deletions

View File

@ -34,7 +34,7 @@ class Download
$files = [];
$album_ids = array_merge([$album->id_tag], $this->getChildAlbumIds($album->id_tag));
foreach($album_ids as $album_id)
foreach ($album_ids as $album_id)
{
$iterator = AssetIterator::getByOptions(['id_tag' => $album_id]);
while ($asset = $iterator->next())
@ -42,8 +42,8 @@ class Download
}
$descriptorspec = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
0 => ['pipe', 'r'], // STDIN
1 => ['pipe', 'w'], // STDOUT
];
$command = 'tar -cf - -C ' . escapeshellarg(ASSETSDIR) . ' --null -T -';
@ -59,22 +59,33 @@ class Download
if(!$pipes[1])
throw new UnexpectedValueException('Could not open pipe for STDOUT');
$album_name = $album->tag;
// STDOUT should not block.
stream_set_blocking($pipes[1], 0);
header('Pragma: no-cache');
header('Content-Description: File Download');
header('Content-disposition: attachment; filename="' . $album_name . '.tar"');
header('Content-disposition: attachment; filename="' . $album->tag . '.tar"');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
foreach($files as $file)
// Write filenames to include to STDIN, separated by null bytes.
foreach ($files as $file)
fwrite($pipes[0], $file . "\0");
// Close STDIN pipe to start archiving.
fclose($pipes[0]);
while($chunk = stream_get_contents($pipes[1], 4096))
echo $chunk;
do
{
// Read STDOUT as `tar` is doing its work.
echo stream_get_contents($pipes[1], 4096);
// Are we still running?
$status = proc_get_status($proc);
}
while (!empty($status) && $status['running']);
// Close STDOUT pipe and clean up process.
fclose($pipes[1]);
proc_close($proc);