Path: blob/1.0-develop/app/Repositories/Wings/DaemonFileRepository.php
7460 views
<?php12namespace Pterodactyl\Repositories\Wings;34use Illuminate\Support\Arr;5use Webmozart\Assert\Assert;6use Pterodactyl\Models\Server;7use Psr\Http\Message\ResponseInterface;8use GuzzleHttp\Exception\ClientException;9use GuzzleHttp\Exception\TransferException;10use Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException;11use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;1213/**14* @method \Pterodactyl\Repositories\Wings\DaemonFileRepository setNode(\Pterodactyl\Models\Node $node)15* @method \Pterodactyl\Repositories\Wings\DaemonFileRepository setServer(\Pterodactyl\Models\Server $server)16*/17class DaemonFileRepository extends DaemonRepository18{19/**20* Return the contents of a given file.21*22* @param int|null $notLargerThan the maximum content length in bytes23*24* @throws TransferException25* @throws FileSizeTooLargeException26* @throws DaemonConnectionException27*/28public function getContent(string $path, ?int $notLargerThan = null): string29{30Assert::isInstanceOf($this->server, Server::class);3132try {33$response = $this->getHttpClient()->get(34sprintf('/api/servers/%s/files/contents', $this->server->uuid),35[36'query' => ['file' => $path],37]38);39} catch (ClientException|TransferException $exception) {40throw new DaemonConnectionException($exception);41}4243$length = (int) Arr::get($response->getHeader('Content-Length'), 0, 0);44if ($notLargerThan && $length > $notLargerThan) {45throw new FileSizeTooLargeException();46}4748return $response->getBody()->__toString();49}5051/**52* Save new contents to a given file. This works for both creating and updating53* a file.54*55* @throws DaemonConnectionException56*/57public function putContent(string $path, string $content): ResponseInterface58{59Assert::isInstanceOf($this->server, Server::class);6061try {62return $this->getHttpClient()->post(63sprintf('/api/servers/%s/files/write', $this->server->uuid),64[65'query' => ['file' => $path],66'body' => $content,67]68);69} catch (TransferException $exception) {70throw new DaemonConnectionException($exception);71}72}7374/**75* Return a directory listing for a given path.76*77* @throws DaemonConnectionException78*/79public function getDirectory(string $path): array80{81Assert::isInstanceOf($this->server, Server::class);8283try {84$response = $this->getHttpClient()->get(85sprintf('/api/servers/%s/files/list-directory', $this->server->uuid),86[87'query' => ['directory' => $path],88]89);90} catch (TransferException $exception) {91throw new DaemonConnectionException($exception);92}9394return json_decode($response->getBody(), true);95}9697/**98* Creates a new directory for the server in the given $path.99*100* @throws DaemonConnectionException101*/102public function createDirectory(string $name, string $path): ResponseInterface103{104Assert::isInstanceOf($this->server, Server::class);105106try {107return $this->getHttpClient()->post(108sprintf('/api/servers/%s/files/create-directory', $this->server->uuid),109[110'json' => [111'name' => $name,112'path' => $path,113],114]115);116} catch (TransferException $exception) {117throw new DaemonConnectionException($exception);118}119}120121/**122* Renames or moves a file on the remote machine.123*124* @throws DaemonConnectionException125*/126public function renameFiles(?string $root, array $files): ResponseInterface127{128Assert::isInstanceOf($this->server, Server::class);129130try {131return $this->getHttpClient()->put(132sprintf('/api/servers/%s/files/rename', $this->server->uuid),133[134'json' => [135'root' => $root ?? '/',136'files' => $files,137],138]139);140} catch (TransferException $exception) {141throw new DaemonConnectionException($exception);142}143}144145/**146* Copy a given file and give it a unique name.147*148* @throws DaemonConnectionException149*/150public function copyFile(string $location): ResponseInterface151{152Assert::isInstanceOf($this->server, Server::class);153154try {155return $this->getHttpClient()->post(156sprintf('/api/servers/%s/files/copy', $this->server->uuid),157[158'json' => [159'location' => $location,160],161]162);163} catch (TransferException $exception) {164throw new DaemonConnectionException($exception);165}166}167168/**169* Delete a file or folder for the server.170*171* @throws DaemonConnectionException172*/173public function deleteFiles(?string $root, array $files): ResponseInterface174{175Assert::isInstanceOf($this->server, Server::class);176177try {178return $this->getHttpClient()->post(179sprintf('/api/servers/%s/files/delete', $this->server->uuid),180[181'json' => [182'root' => $root ?? '/',183'files' => $files,184],185]186);187} catch (TransferException $exception) {188throw new DaemonConnectionException($exception);189}190}191192/**193* Compress the given files or folders in the given root.194*195* @throws DaemonConnectionException196*/197public function compressFiles(?string $root, array $files): array198{199Assert::isInstanceOf($this->server, Server::class);200201try {202$response = $this->getHttpClient()->post(203sprintf('/api/servers/%s/files/compress', $this->server->uuid),204[205'json' => [206'root' => $root ?? '/',207'files' => $files,208],209// Wait for up to 15 minutes for the archive to be completed when calling this endpoint210// since it will likely take quite awhile for large directories.211'timeout' => 60 * 15,212]213);214} catch (TransferException $exception) {215throw new DaemonConnectionException($exception);216}217218return json_decode($response->getBody(), true);219}220221/**222* Decompresses a given archive file.223*224* @throws DaemonConnectionException225*/226public function decompressFile(?string $root, string $file): ResponseInterface227{228Assert::isInstanceOf($this->server, Server::class);229230try {231return $this->getHttpClient()->post(232sprintf('/api/servers/%s/files/decompress', $this->server->uuid),233[234'json' => [235'root' => $root ?? '/',236'file' => $file,237],238// Wait for up to 15 minutes for the decompress to be completed when calling this endpoint239// since it will likely take quite awhile for large directories.240'timeout' => 60 * 15,241]242);243} catch (TransferException $exception) {244throw new DaemonConnectionException($exception);245}246}247248/**249* Chmods the given files.250*251* @throws DaemonConnectionException252*/253public function chmodFiles(?string $root, array $files): ResponseInterface254{255Assert::isInstanceOf($this->server, Server::class);256257try {258return $this->getHttpClient()->post(259sprintf('/api/servers/%s/files/chmod', $this->server->uuid),260[261'json' => [262'root' => $root ?? '/',263'files' => $files,264],265]266);267} catch (TransferException $exception) {268throw new DaemonConnectionException($exception);269}270}271272/**273* Pulls a file from the given URL and saves it to the disk.274*275* @throws DaemonConnectionException276*/277public function pull(string $url, ?string $directory, array $params = []): ResponseInterface278{279Assert::isInstanceOf($this->server, Server::class);280281$attributes = [282'url' => $url,283'root' => $directory ?? '/',284'file_name' => $params['filename'] ?? null,285'use_header' => $params['use_header'] ?? null,286'foreground' => $params['foreground'] ?? null,287];288289try {290return $this->getHttpClient()->post(291sprintf('/api/servers/%s/files/pull', $this->server->uuid),292[293'json' => array_filter($attributes, fn ($value) => !is_null($value)),294]295);296} catch (TransferException $exception) {297throw new DaemonConnectionException($exception);298}299}300}301302303