Reputation: 305
I’m trying to download a video from an extrernal URL using symfony. So i have this route, if i click on it directly in the browser, I receive two possible answers: the video is played or (if the browser is unable to reproduce it), the video is downloaded from this external URL. What i’m trying to create is a response from the Controller to always download the video. I’ve tried several solution with no luck.
Some tried solutions:
$response = new BinaryFileResponse($url);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
return $response;
Since it’s not a static file is failing.
Also tried
$response = new RedirectResponse($url);
$response->headers->set('Content-Type', 'video');
$d = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$videoUrl
);
$response->headers->set('Content-Disposition', $d);
And of course the ‘StreamedResponse’… I'm assuming this is possible since i'm getting the desired behavior when the format is not properly traduced in the browser... Any help is appreciated.
Upvotes: 2
Views: 4057
Reputation: 6560
I don't think BinaryFileResponse
works with URLs. You should be getting an exception about the file not being readable.
Take a look at StreamedResponse
. You can use a custom callback to stream any data to the browser:
use Symfony\Component\HttpFoundation\StreamedResponse;
// ...
$response = new StreamedResponse();
// attempt to generate a filename from the URL's path
$filename = @preg_replace('~[^\w\-.]+~', '', iconv('UTF-8', 'ASCII//TRANSLIT', pathinfo(urldecode(parse_url($url, PHP_URL_PATH)), PATHINFO_BASENAME))) ?: 'video';
// set headers to force file download
$response->headers->set('Content-Type', 'application/force-download');
$response->headers->set(
'Content-Disposition',
$response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$filename
)
);
// stream content from the URL to the browser
$response->setCallback(function () use ($url) {
$c = curl_init($url);
curl_exec($c);
curl_close($c);
});
$url
comes from the user you need to validate it (if you don't then users can abuse it)Regarding your other attempt:
makeDisposition()
should be a ASCII file name, not an URLRedirectResponse
- it just redirects the browser so the Content-Disposition will not apply to the destination URLUpvotes: 6