Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Repositories/Wings/DaemonFileRepository.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Repositories\Wings;
4
5
use Illuminate\Support\Arr;
6
use Webmozart\Assert\Assert;
7
use Pterodactyl\Models\Server;
8
use Psr\Http\Message\ResponseInterface;
9
use GuzzleHttp\Exception\ClientException;
10
use GuzzleHttp\Exception\TransferException;
11
use Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException;
12
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
13
14
/**
15
* @method \Pterodactyl\Repositories\Wings\DaemonFileRepository setNode(\Pterodactyl\Models\Node $node)
16
* @method \Pterodactyl\Repositories\Wings\DaemonFileRepository setServer(\Pterodactyl\Models\Server $server)
17
*/
18
class DaemonFileRepository extends DaemonRepository
19
{
20
/**
21
* Return the contents of a given file.
22
*
23
* @param int|null $notLargerThan the maximum content length in bytes
24
*
25
* @throws TransferException
26
* @throws FileSizeTooLargeException
27
* @throws DaemonConnectionException
28
*/
29
public function getContent(string $path, ?int $notLargerThan = null): string
30
{
31
Assert::isInstanceOf($this->server, Server::class);
32
33
try {
34
$response = $this->getHttpClient()->get(
35
sprintf('/api/servers/%s/files/contents', $this->server->uuid),
36
[
37
'query' => ['file' => $path],
38
]
39
);
40
} catch (ClientException|TransferException $exception) {
41
throw new DaemonConnectionException($exception);
42
}
43
44
$length = (int) Arr::get($response->getHeader('Content-Length'), 0, 0);
45
if ($notLargerThan && $length > $notLargerThan) {
46
throw new FileSizeTooLargeException();
47
}
48
49
return $response->getBody()->__toString();
50
}
51
52
/**
53
* Save new contents to a given file. This works for both creating and updating
54
* a file.
55
*
56
* @throws DaemonConnectionException
57
*/
58
public function putContent(string $path, string $content): ResponseInterface
59
{
60
Assert::isInstanceOf($this->server, Server::class);
61
62
try {
63
return $this->getHttpClient()->post(
64
sprintf('/api/servers/%s/files/write', $this->server->uuid),
65
[
66
'query' => ['file' => $path],
67
'body' => $content,
68
]
69
);
70
} catch (TransferException $exception) {
71
throw new DaemonConnectionException($exception);
72
}
73
}
74
75
/**
76
* Return a directory listing for a given path.
77
*
78
* @throws DaemonConnectionException
79
*/
80
public function getDirectory(string $path): array
81
{
82
Assert::isInstanceOf($this->server, Server::class);
83
84
try {
85
$response = $this->getHttpClient()->get(
86
sprintf('/api/servers/%s/files/list-directory', $this->server->uuid),
87
[
88
'query' => ['directory' => $path],
89
]
90
);
91
} catch (TransferException $exception) {
92
throw new DaemonConnectionException($exception);
93
}
94
95
return json_decode($response->getBody(), true);
96
}
97
98
/**
99
* Creates a new directory for the server in the given $path.
100
*
101
* @throws DaemonConnectionException
102
*/
103
public function createDirectory(string $name, string $path): ResponseInterface
104
{
105
Assert::isInstanceOf($this->server, Server::class);
106
107
try {
108
return $this->getHttpClient()->post(
109
sprintf('/api/servers/%s/files/create-directory', $this->server->uuid),
110
[
111
'json' => [
112
'name' => $name,
113
'path' => $path,
114
],
115
]
116
);
117
} catch (TransferException $exception) {
118
throw new DaemonConnectionException($exception);
119
}
120
}
121
122
/**
123
* Renames or moves a file on the remote machine.
124
*
125
* @throws DaemonConnectionException
126
*/
127
public function renameFiles(?string $root, array $files): ResponseInterface
128
{
129
Assert::isInstanceOf($this->server, Server::class);
130
131
try {
132
return $this->getHttpClient()->put(
133
sprintf('/api/servers/%s/files/rename', $this->server->uuid),
134
[
135
'json' => [
136
'root' => $root ?? '/',
137
'files' => $files,
138
],
139
]
140
);
141
} catch (TransferException $exception) {
142
throw new DaemonConnectionException($exception);
143
}
144
}
145
146
/**
147
* Copy a given file and give it a unique name.
148
*
149
* @throws DaemonConnectionException
150
*/
151
public function copyFile(string $location): ResponseInterface
152
{
153
Assert::isInstanceOf($this->server, Server::class);
154
155
try {
156
return $this->getHttpClient()->post(
157
sprintf('/api/servers/%s/files/copy', $this->server->uuid),
158
[
159
'json' => [
160
'location' => $location,
161
],
162
]
163
);
164
} catch (TransferException $exception) {
165
throw new DaemonConnectionException($exception);
166
}
167
}
168
169
/**
170
* Delete a file or folder for the server.
171
*
172
* @throws DaemonConnectionException
173
*/
174
public function deleteFiles(?string $root, array $files): ResponseInterface
175
{
176
Assert::isInstanceOf($this->server, Server::class);
177
178
try {
179
return $this->getHttpClient()->post(
180
sprintf('/api/servers/%s/files/delete', $this->server->uuid),
181
[
182
'json' => [
183
'root' => $root ?? '/',
184
'files' => $files,
185
],
186
]
187
);
188
} catch (TransferException $exception) {
189
throw new DaemonConnectionException($exception);
190
}
191
}
192
193
/**
194
* Compress the given files or folders in the given root.
195
*
196
* @throws DaemonConnectionException
197
*/
198
public function compressFiles(?string $root, array $files): array
199
{
200
Assert::isInstanceOf($this->server, Server::class);
201
202
try {
203
$response = $this->getHttpClient()->post(
204
sprintf('/api/servers/%s/files/compress', $this->server->uuid),
205
[
206
'json' => [
207
'root' => $root ?? '/',
208
'files' => $files,
209
],
210
// Wait for up to 15 minutes for the archive to be completed when calling this endpoint
211
// since it will likely take quite awhile for large directories.
212
'timeout' => 60 * 15,
213
]
214
);
215
} catch (TransferException $exception) {
216
throw new DaemonConnectionException($exception);
217
}
218
219
return json_decode($response->getBody(), true);
220
}
221
222
/**
223
* Decompresses a given archive file.
224
*
225
* @throws DaemonConnectionException
226
*/
227
public function decompressFile(?string $root, string $file): ResponseInterface
228
{
229
Assert::isInstanceOf($this->server, Server::class);
230
231
try {
232
return $this->getHttpClient()->post(
233
sprintf('/api/servers/%s/files/decompress', $this->server->uuid),
234
[
235
'json' => [
236
'root' => $root ?? '/',
237
'file' => $file,
238
],
239
// Wait for up to 15 minutes for the decompress to be completed when calling this endpoint
240
// since it will likely take quite awhile for large directories.
241
'timeout' => 60 * 15,
242
]
243
);
244
} catch (TransferException $exception) {
245
throw new DaemonConnectionException($exception);
246
}
247
}
248
249
/**
250
* Chmods the given files.
251
*
252
* @throws DaemonConnectionException
253
*/
254
public function chmodFiles(?string $root, array $files): ResponseInterface
255
{
256
Assert::isInstanceOf($this->server, Server::class);
257
258
try {
259
return $this->getHttpClient()->post(
260
sprintf('/api/servers/%s/files/chmod', $this->server->uuid),
261
[
262
'json' => [
263
'root' => $root ?? '/',
264
'files' => $files,
265
],
266
]
267
);
268
} catch (TransferException $exception) {
269
throw new DaemonConnectionException($exception);
270
}
271
}
272
273
/**
274
* Pulls a file from the given URL and saves it to the disk.
275
*
276
* @throws DaemonConnectionException
277
*/
278
public function pull(string $url, ?string $directory, array $params = []): ResponseInterface
279
{
280
Assert::isInstanceOf($this->server, Server::class);
281
282
$attributes = [
283
'url' => $url,
284
'root' => $directory ?? '/',
285
'file_name' => $params['filename'] ?? null,
286
'use_header' => $params['use_header'] ?? null,
287
'foreground' => $params['foreground'] ?? null,
288
];
289
290
try {
291
return $this->getHttpClient()->post(
292
sprintf('/api/servers/%s/files/pull', $this->server->uuid),
293
[
294
'json' => array_filter($attributes, fn ($value) => !is_null($value)),
295
]
296
);
297
} catch (TransferException $exception) {
298
throw new DaemonConnectionException($exception);
299
}
300
}
301
}
302
303