* @template-extends Response> */ class StreamResponse extends Response implements ICallbackResponse { /** @var string */ private $filePath; /** * @param string|resource $filePath the path to the file or a file handle which should be streamed * @param S $status * @param H $headers * @since 8.1.0 */ public function __construct(mixed $filePath, int $status = Http::STATUS_OK, array $headers = []) { parent::__construct($status, $headers); $this->filePath = $filePath; } /** * Streams the file using readfile * * @param IOutput $output a small wrapper that handles output * @since 8.1.0 */ public function callback(IOutput $output) { // handle caching if ($output->getHttpResponseCode() !== Http::STATUS_NOT_MODIFIED) { if (!(is_resource($this->filePath) || file_exists($this->filePath))) { $output->setHttpResponseCode(Http::STATUS_NOT_FOUND); } elseif ($output->setReadfile($this->filePath) === false) { $output->setHttpResponseCode(Http::STATUS_BAD_REQUEST); } } } }