public function setFile(
        $file,
        string $contentDisposition = null,
        bool $autoETag             = false,
        bool $autoLastModified     = true
    ): ResponseInterface {
        if (! $file instanceof File) {
            if ($file instanceof SplFileInfo) {
                $file = new File($file->getPathname());
            } elseif (\is_string($file)) {
                $file = new File($file);
            } else {
                throw new InvalidArgumentException(\sprintf(
                    'Invalid content [%s] provided to %s.',
                    (\is_object($file) ? \get_class($file) : \gettype($file)),
                    __CLASS__
                ));
            }
        }

        if (! $file->isReadable()) {
            throw new FileException('File must be readable.');
        }

        $this->file = $file;

        if ($autoETag === true) {
            $this->setAutoEtag();
        }

        if ($autoLastModified === true) {
            $this->setAutoLastModified();
        }

        if ($contentDisposition) {
            $this->headers['Content-Length']      = [$this->file->getSize()];
            $this->headers['Content-Disposition'] = [
                InteractsWithDisposition::makeDisposition(
                    $contentDisposition,
                    $this->file->getFilename(),
                    InteractsWithDisposition::encodedFallbackFilename($this->file->getFilename())
                ),
            ];

            $this->headerNames['content-length']      = 'Content-Length';
            $this->headerNames['content-disposition'] = 'Content-Disposition';

            if (! $this->hasHeader('Content-Type')) {
                $this->headers['Content-Type']     = [$this->file->getMimeType() ?? 'application/octet-stream'];
                $this->headerNames['content-type'] = 'Content-Type';
            }
        }

        return $this;
    }