mirror of
https://code.castopod.org/adaures/castopod.git
synced 2024-10-05 16:06:51 +02:00
fix(import): rewrite download_file helper to output curl response directly to file
This prevents memory exhaustion when downloading large files
This commit is contained in:
parent
281eefc6a3
commit
eb7ad2f7e1
@ -136,7 +136,9 @@ if (! function_exists('publication_pill')) {
|
||||
$customClass .
|
||||
'">' .
|
||||
$label .
|
||||
($publicationStatus === 'with_podcast' ? '<Icon glyph="error-warning" class="flex-shrink-0 ml-1 text-lg" />' : '') .
|
||||
($publicationStatus === 'with_podcast' ? icon('error-warning-fill', [
|
||||
'class' => 'flex-shrink-0 ml-1 text-lg',
|
||||
]) : '') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
|
@ -9,47 +9,12 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
use CodeIgniter\Files\File;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\Mimes;
|
||||
use Config\Services;
|
||||
|
||||
if (! function_exists('download_file')) {
|
||||
function download_file(string $fileUrl, string $mimetype = ''): File
|
||||
{
|
||||
$client = Services::curlrequest();
|
||||
|
||||
$response = $client->get($fileUrl, [
|
||||
'headers' => [
|
||||
'User-Agent' => 'Castopod/' . CP_VERSION,
|
||||
],
|
||||
]);
|
||||
|
||||
// redirect to new file location
|
||||
$newFileUrl = $fileUrl;
|
||||
while (
|
||||
in_array(
|
||||
$response->getStatusCode(),
|
||||
[
|
||||
ResponseInterface::HTTP_MOVED_PERMANENTLY,
|
||||
ResponseInterface::HTTP_FOUND,
|
||||
ResponseInterface::HTTP_SEE_OTHER,
|
||||
ResponseInterface::HTTP_NOT_MODIFIED,
|
||||
ResponseInterface::HTTP_TEMPORARY_REDIRECT,
|
||||
ResponseInterface::HTTP_PERMANENT_REDIRECT,
|
||||
],
|
||||
true,
|
||||
)
|
||||
) {
|
||||
$newFileUrl = trim($response->header('location')->getValue());
|
||||
$response = $client->get($newFileUrl, [
|
||||
'headers' => [
|
||||
'User-Agent' => 'Castopod/' . CP_VERSION,
|
||||
],
|
||||
'http_errors' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
$fileExtension = pathinfo(parse_url($newFileUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
$fileExtension = pathinfo(parse_url($fileUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
$extension = $fileExtension === '' ? Mimes::guessExtensionFromType($mimetype) : $fileExtension;
|
||||
$tmpFilename =
|
||||
time() .
|
||||
@ -57,9 +22,26 @@ if (! function_exists('download_file')) {
|
||||
bin2hex(random_bytes(10)) .
|
||||
'.' .
|
||||
$extension;
|
||||
$tmpfileKey = WRITEPATH . 'uploads/' . $tmpFilename;
|
||||
file_put_contents($tmpfileKey, $response->getBody());
|
||||
$tmpfilePath = WRITEPATH . 'uploads/' . $tmpFilename;
|
||||
|
||||
return new File($tmpfileKey);
|
||||
$file = fopen($tmpfilePath, 'w');
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $fileUrl);
|
||||
|
||||
// output directly to file
|
||||
curl_setopt($ch, CURLOPT_FILE, $file);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['User-Agent: Castopod/' . CP_VERSION]);
|
||||
|
||||
// follow redirects up to 20, like Apple Podcasts
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, 20);
|
||||
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
fclose($file);
|
||||
|
||||
return new File($tmpfilePath);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ $isEpisodeArea = isset($podcast) && isset($episode);
|
||||
<div class="flex flex-wrap items-center truncate">
|
||||
<?php if (($isEpisodeArea && $episode->is_premium) || ($isPodcastArea && $podcast->is_premium)): ?>
|
||||
<div class="inline-flex items-center">
|
||||
<?php // @icon('exchange-dollar-fill')?>
|
||||
<IconButton uri="<?= route_to('subscription-list', $podcast->id) ?>" glyph="exchange-dollar-fill" variant="secondary" size="large" class="p-0 mr-2 border-0"><?= ($isEpisodeArea && $episode->is_premium) ? lang('PremiumPodcasts.episode_is_premium') : lang('PremiumPodcasts.podcast_is_premium') ?></IconButton>
|
||||
<Heading tagName="h1" size="large" class="truncate"><?= $this->renderSection('pageTitle') ?></Heading>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user