pathPrefixer = new PathPrefixer($root); } /** * Writes at most `$maxBytes` bytes, so a file that grew since its size was read cannot overrun the response. * phpseclib calls fstat() on a resource destination, which php://output does not support, so it gets a callable. */ public function download(string $path, $destination, int $maxBytes): void { $write = function (string $chunk) use ($destination): void { fwrite($destination, $chunk); }; try { $downloaded = $this->connections->provideConnection()->get($this->pathPrefixer->prefixPath($path), $write, 0, $maxBytes); } catch (Throwable $exception) { throw UnableToReadFile::fromLocation($path, $exception->getMessage(), $exception); } if ($downloaded === false) { throw UnableToReadFile::fromLocation($path); } } /** * RMDIR, which the server refuses for a directory that is not empty. deleteDirectory() deletes the content first. */ public function deleteEmptyDirectory(string $path): bool { return $this->connections->provideConnection()->rmdir($this->pathPrefixer->prefixPath($path)); } /** * The host key that the server presented, as " ". */ public function presentedHostKey(): ?string { return $this->connections->presentedHostKey(); } }