Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

antogkou's avatar

Stream file from an external api call to browser without caching

So I’ve been trying to solve a challenge lately and would love this community’s input on it.

The challenge: stream a file to the users browser without caching it in php. The file is coming through an http call (the file is in a salesforce and i am getting it through a simple API call)

I’ve tried downloading to storage - then serve it to the user, works fine but I have to wait for laravel to save it - serve it and then delete it.

Next step was to use fopen and stream the file without saving - which leads to instantly start the download for the user without first waiting for it to arrive in laravel storage. Problem is - something is limiting the download to around 200-300kb/s

I’m looking for ideas to serve the file while the http call is happening, meaning php will work as a ‘proxy’.

I hope my description makes sense. Will post my controller code too.

0 likes
3 replies
antogkou's avatar

@Sinnbeck that's exactly what I'm using - am I doing it wrong though? This is my full code for doing that.

public function __invoke(Request $request): StreamedResponse
    {
        $validated = $request->validate([
            'id' => 'required|string',
            'name' => 'required|string',
            'size' => 'required|integer',
        ]);
        $params = $validated['id'] . '/VersionData';
        $token = $this->token();
        $url = $request->path ?? (config('salesforce.document_uri') . $params);
        $options = [
            'http' => [
                'method' => "GET",
                'header' => "Authorization: Bearer $token",
            ]
        ];
        $defineContext = stream_context_create($options);
        $file = fopen($url, 'rb', false, $defineContext);

        $headers = [
            'Content-Type' => 'application/octet-stream',
            'Content-Length' => $validated['size'],
            'Content-Transfer-Encoding' => 'binary',
            'Content-Disposition' => 'attachment; filename=' . $validated['name'],
        ];

        return response()->streamDownload(function () use ($file) {
            // @codeCoverageIgnoreStart
            fpassthru($file);
            fclose($file);
            // @codeCoverageIgnoreEnd
        }, $validated['name'], $headers);
    }
Sinnbeck's avatar

@antogkou I have only used it myself in the exact way as shown in the docs. But maybe try an move the complete logic inside the callback

Please or to participate in this conversation.