| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- <?php
- declare(strict_types=1);
- // POST api/v1/backup.php
- // Receives a backup archive from an authenticated instance.
- //
- // multipart/form-data fields:
- // filename backup-YYYYmmdd-HHMMSS[-N].zip
- // sha256 client-side checksum, re-verified here
- // meta optional JSON (trigger, file_count, source_bytes, app_version)
- // backup the ZIP file itself
- require_once __DIR__ . "/../../includes/api.php";
- require_once __DIR__ . "/../../includes/backups.php";
- manageApiRequireMethod("POST");
- $instance = manageApiAuthenticate();
- try {
- $file = $_FILES["backup"] ?? null;
- if (!is_array($file)) {
- throw new RuntimeException("Backup-Datei fehlt.");
- }
- $uploadError = (int) ($file["error"] ?? UPLOAD_ERR_NO_FILE);
- if ($uploadError !== UPLOAD_ERR_OK) {
- // INI_SIZE / FORM_SIZE are the common real-world failure and deserve a
- // message that names the cause instead of a bare error code.
- if ($uploadError === UPLOAD_ERR_INI_SIZE || $uploadError === UPLOAD_ERR_FORM_SIZE) {
- throw new RuntimeException(
- "Backup überschreitet das Upload-Limit des Servers (upload_max_filesize / post_max_size).",
- );
- }
- throw new RuntimeException("Upload fehlgeschlagen (Fehlercode " . $uploadError . ").");
- }
- $tmpName = (string) ($file["tmp_name"] ?? "");
- if ($tmpName === "" || !is_uploaded_file($tmpName)) {
- throw new RuntimeException("Upload ist ungültig.");
- }
- $maxBytes = (int) MANAGE_BACKUP_MAX_UPLOAD_BYTES;
- if ($maxBytes > 0 && (int) ($file["size"] ?? 0) > $maxBytes) {
- throw new RuntimeException("Backup überschreitet die konfigurierte Maximalgröße.");
- }
- if (!manageFileIsZip($tmpName)) {
- throw new RuntimeException("Die hochgeladene Datei muss ein ZIP-Archiv sein.");
- }
- $meta = [];
- $rawMeta = trim((string) ($_POST["meta"] ?? ""));
- if ($rawMeta !== "") {
- $decoded = json_decode($rawMeta, true);
- if (is_array($decoded)) {
- $meta = $decoded;
- }
- }
- $result = manageBackupStoreUpload(
- $instance["id"],
- $tmpName,
- (string) ($_POST["filename"] ?? ""),
- (string) ($_POST["sha256"] ?? ""),
- $meta,
- );
- manageApiSendJson(200, array_merge(["success" => true, "instance" => $instance["id"]], $result));
- } catch (Throwable $exception) {
- manageLogError("Backup upload rejected", [
- "instance" => $instance["id"],
- "error" => $exception->getMessage(),
- ]);
- manageApiFail(400, $exception->getMessage());
- }
|