Deploy Ladill Hosting / deploy (push) Failing after 17s
Shared web hosting extracted from the platform monolith, with CI deploy to /var/www/ladill-hosting matching Bird/Domains/Email. Co-authored-by: Cursor <cursoragent@cursor.com>
160 lines
4.5 KiB
PHP
160 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Hosting;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\HostingAccount;
|
|
use App\Services\Hosting\BrowserTerminalSessionManager;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class HostingTerminalSessionController extends Controller
|
|
{
|
|
public function __construct(
|
|
private BrowserTerminalSessionManager $sessionManager,
|
|
) {}
|
|
|
|
public function start(Request $request, HostingAccount $account): JsonResponse
|
|
{
|
|
$this->authorize('useTerminal', $account);
|
|
$account->loadMissing('node');
|
|
|
|
$validated = $request->validate([
|
|
'path' => 'nullable|string|max:255',
|
|
'cols' => 'nullable|integer|min:40|max:240',
|
|
'rows' => 'nullable|integer|min:10|max:80',
|
|
]);
|
|
|
|
$session = $this->sessionManager->createSession(
|
|
$account,
|
|
(int) $request->user()->id,
|
|
(string) ($validated['path'] ?? '/public_html'),
|
|
(int) ($validated['cols'] ?? 120),
|
|
(int) ($validated['rows'] ?? 30),
|
|
);
|
|
|
|
return response()->json([
|
|
'session_id' => $session['session_id'],
|
|
'status' => $session['status'],
|
|
]);
|
|
}
|
|
|
|
public function read(Request $request, HostingAccount $account, string $session): JsonResponse
|
|
{
|
|
$this->authorize('useTerminal', $account);
|
|
|
|
try {
|
|
$payload = $this->sessionManager->readOutput(
|
|
$account,
|
|
(int) $request->user()->id,
|
|
$session,
|
|
(int) $request->integer('offset', 0),
|
|
);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['message' => $e->getMessage()], 404);
|
|
}
|
|
|
|
return response()->json($payload);
|
|
}
|
|
|
|
public function input(Request $request, HostingAccount $account, string $session): JsonResponse
|
|
{
|
|
$this->authorize('useTerminal', $account);
|
|
|
|
$input = $this->extractTerminalInput($request);
|
|
|
|
if ($input === null) {
|
|
return response()->json(['message' => 'Invalid terminal input payload.'], 422);
|
|
}
|
|
|
|
if (strlen($input) > 8192) {
|
|
return response()->json(['message' => 'Terminal input payload is too large.'], 422);
|
|
}
|
|
|
|
if ($input === '') {
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
|
|
try {
|
|
$this->sessionManager->appendInput(
|
|
$account,
|
|
(int) $request->user()->id,
|
|
$session,
|
|
$input,
|
|
);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['message' => $e->getMessage()], 404);
|
|
}
|
|
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
|
|
public function resize(Request $request, HostingAccount $account, string $session): JsonResponse
|
|
{
|
|
$this->authorize('useTerminal', $account);
|
|
|
|
$validated = $request->validate([
|
|
'cols' => 'required|integer|min:40|max:240',
|
|
'rows' => 'required|integer|min:10|max:80',
|
|
]);
|
|
|
|
try {
|
|
$this->sessionManager->resizeSession(
|
|
$account,
|
|
(int) $request->user()->id,
|
|
$session,
|
|
(int) $validated['cols'],
|
|
(int) $validated['rows'],
|
|
);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['message' => $e->getMessage()], 404);
|
|
}
|
|
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
|
|
public function close(Request $request, HostingAccount $account, string $session): JsonResponse
|
|
{
|
|
$this->authorize('useTerminal', $account);
|
|
|
|
try {
|
|
$this->sessionManager->closeSession(
|
|
$account,
|
|
(int) $request->user()->id,
|
|
$session,
|
|
);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['message' => $e->getMessage()], 404);
|
|
}
|
|
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
|
|
private function extractTerminalInput(Request $request): ?string
|
|
{
|
|
$input = $request->input('input');
|
|
|
|
if (is_string($input)) {
|
|
return $input;
|
|
}
|
|
|
|
$raw = $request->getContent();
|
|
|
|
if (! is_string($raw)) {
|
|
return null;
|
|
}
|
|
|
|
if ($raw === '') {
|
|
return '';
|
|
}
|
|
|
|
$decoded = json_decode($raw, true);
|
|
|
|
if (is_array($decoded) && array_key_exists('input', $decoded) && is_string($decoded['input'])) {
|
|
return $decoded['input'];
|
|
}
|
|
|
|
return $raw;
|
|
}
|
|
}
|