4

I have a controller with a download action in TYPO3. For some time I have implemented it like this and it is working:

function downloadAction() {
  // ...
  // send headers ...
  // ...
  if ($fh = fopen($this->file, 'r')) {
    while (!feof($fh)) {
      echo fread($fh, $chunkSize); // send file in little chunks to output buffer
      flush();
    }
    fclose($fh);
  }
  exit; // Stopp middlewares and so on.
}

I am wondering if I should/could return an object of type ResponseInterface in TYPO3 11. So it is obviously that exit stops the middleware pipeline and other things and I don't really know if there are any side effects.

I tried the following to return a ResponseInterface:

function downloadAction(): ResponseInterface {
  // ...
  return $this->responseFactory->createResponse();
    ->withAddedHeader(...)
    // ...
    ->withBody($this->streamFactory->createStreamFromFile($this->file))
    ->withStatus(200, 'OK');
}

The problem is that the solution with the ResponseInterface works only with small files. The problem seems to be in Bootstrap::handleFrontendRequest().

protected function handleFrontendRequest(ServerRequestInterface $request): string
{
  // ...
  if (headers_sent() === false) {
    // send headers      
  }
  $body = $response->getBody(); // get the stream
  $body->rewind();
  $content = $body->getContents(); // Problem: Read the hole stream into RAM instead of
                                   // sending it in chunks to the output buffer
  // ...
  return $content;
}

TYPO3 tries to read the whole stream/file into RAM. That crashes the application.

So how should I trigger a file download these days with TYPO3?

nito
  • 1,157
  • 8
  • 21
koalabruder
  • 2,794
  • 9
  • 33
  • 40
  • Have you found a valid solution for this question or do you still use the exit way of doing it? – denis Jun 15 '23 at 07:11

0 Answers0