From c8260df6fd05280226fa65f57f49fad7dc439991 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Tue, 24 Feb 2026 23:45:10 +0000 Subject: [PATCH 1/6] fix: remove strtolower on resources to preserve camelCase --- src/Migration/Transfer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Migration/Transfer.php b/src/Migration/Transfer.php index b4da500..3a8e945 100644 --- a/src/Migration/Transfer.php +++ b/src/Migration/Transfer.php @@ -232,7 +232,6 @@ public function run( } /** @var array $computedResources */ - $computedResources = array_map('strtolower', $computedResources); if ($rootResourceId !== '') { if ($rootResourceType === '') { From 987d11c9f744348908b5af237291cf2be5a66e9e Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Tue, 24 Feb 2026 23:51:51 +0000 Subject: [PATCH 2/6] fix: use camelCase for multi-word resource type values --- src/Migration/Resource.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Migration/Resource.php b/src/Migration/Resource.php index e338385..cee7ded 100644 --- a/src/Migration/Resource.php +++ b/src/Migration/Resource.php @@ -52,13 +52,13 @@ abstract class Resource implements \JsonSerializable public const TYPE_DEPLOYMENT = 'deployment'; - public const TYPE_SITE_DEPLOYMENT = 'site-deployment'; + public const TYPE_SITE_DEPLOYMENT = 'siteDeployment'; - public const TYPE_SITE_VARIABLE = 'site-variable'; + public const TYPE_SITE_VARIABLE = 'siteVariable'; public const TYPE_HASH = 'hash'; - public const TYPE_ENVIRONMENT_VARIABLE = 'environment-variable'; + public const TYPE_ENVIRONMENT_VARIABLE = 'environmentVariable'; // legacy terminologies public const TYPE_DOCUMENT = 'document'; From 8b1b42d89a7b2b89fe75de6b5f1e817ed8508829 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 25 Feb 2026 09:11:44 +0000 Subject: [PATCH 3/6] fix: deployment download bugs in exportDeploymentData and exportSiteDeploymentData - Use lowercase 'content-length' header key (Target::call stores headers lowercase via strtolower) - Use strlen instead of mb_strlen for binary file data (mb_strlen misinterprets gzip bytes as UTF-8) - Cap $end to $fileSize - 1 before first chunked Range request (server rejects $end >= $size with 416) --- src/Migration/Sources/Appwrite.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index c99b667..df1b2d3 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -1704,8 +1704,8 @@ private function exportDeploymentData(Func $func, array $deployment): void $responseHeaders ); - // Content-Length header was missing, file is less than max buffer size. - if (!array_key_exists('Content-Length', $responseHeaders)) { + // content-length header was missing, file is less than max buffer size. + if (!array_key_exists('content-length', $responseHeaders)) { $file = $this->call( 'GET', "/functions/{$func->getId()}/deployments/{$deployment['$id']}/download", @@ -1714,7 +1714,7 @@ private function exportDeploymentData(Func $func, array $deployment): void $responseHeaders ); - $size = mb_strlen($file); + $size = strlen($file); if ($end > $size) { $end = $size - 1; @@ -1737,7 +1737,11 @@ private function exportDeploymentData(Func $func, array $deployment): void return; } - $fileSize = $responseHeaders['Content-Length']; + $fileSize = $responseHeaders['content-length']; + + if ($end > $fileSize - 1) { + $end = $fileSize - 1; + } $deployment = new Deployment( $deployment['$id'], @@ -1920,7 +1924,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void $responseHeaders ); - if (!\array_key_exists('Content-Length', $responseHeaders)) { + if (!\array_key_exists('content-length', $responseHeaders)) { $file = $this->call( 'GET', "/sites/{$site->getId()}/deployments/{$deployment['$id']}/download", @@ -1929,7 +1933,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void $responseHeaders ); - $size = mb_strlen($file); + $size = strlen($file); if ($end > $size) { $end = $size - 1; @@ -1951,7 +1955,11 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void return; } - $fileSize = $responseHeaders['Content-Length']; + $fileSize = $responseHeaders['content-length']; + + if ($end > $fileSize - 1) { + $end = $fileSize - 1; + } $siteDeployment = new SiteDeployment( $deployment['$id'], From 261bc058a5c8faba71ad5f8efb4284f2d128feea Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 25 Feb 2026 09:29:21 +0000 Subject: [PATCH 4/6] Revert "fix: use camelCase for multi-word resource type values" This reverts commit 987d11c9f744348908b5af237291cf2be5a66e9e. --- src/Migration/Resource.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Migration/Resource.php b/src/Migration/Resource.php index cee7ded..e338385 100644 --- a/src/Migration/Resource.php +++ b/src/Migration/Resource.php @@ -52,13 +52,13 @@ abstract class Resource implements \JsonSerializable public const TYPE_DEPLOYMENT = 'deployment'; - public const TYPE_SITE_DEPLOYMENT = 'siteDeployment'; + public const TYPE_SITE_DEPLOYMENT = 'site-deployment'; - public const TYPE_SITE_VARIABLE = 'siteVariable'; + public const TYPE_SITE_VARIABLE = 'site-variable'; public const TYPE_HASH = 'hash'; - public const TYPE_ENVIRONMENT_VARIABLE = 'environmentVariable'; + public const TYPE_ENVIRONMENT_VARIABLE = 'environment-variable'; // legacy terminologies public const TYPE_DOCUMENT = 'document'; From 3190013af7e167258bad3ae90db7176a0d8cb31e Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 25 Feb 2026 09:29:21 +0000 Subject: [PATCH 5/6] Revert "fix: remove strtolower on resources to preserve camelCase" This reverts commit c8260df6fd05280226fa65f57f49fad7dc439991. --- src/Migration/Transfer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Migration/Transfer.php b/src/Migration/Transfer.php index 3a8e945..b4da500 100644 --- a/src/Migration/Transfer.php +++ b/src/Migration/Transfer.php @@ -232,6 +232,7 @@ public function run( } /** @var array $computedResources */ + $computedResources = array_map('strtolower', $computedResources); if ($rootResourceId !== '') { if ($rootResourceType === '') { From 134efdc72bf2fed59d98c07eb8e6a2e6fee64e67 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 25 Feb 2026 11:33:23 +0000 Subject: [PATCH 6/6] fix: use consistent end >= fileSize range clamping --- src/Migration/Sources/Appwrite.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index df1b2d3..47a0346 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -1471,7 +1471,7 @@ private function exportFileData(File $file): void // Get the file size $fileSize = $file->getSize(); - if ($end > $fileSize) { + if ($end >= $fileSize) { $end = $fileSize - 1; } @@ -1495,7 +1495,7 @@ private function exportFileData(File $file): void $start += Transfer::STORAGE_MAX_CHUNK_SIZE; $end += Transfer::STORAGE_MAX_CHUNK_SIZE; - if ($end > $fileSize) { + if ($end >= $fileSize) { $end = $fileSize - 1; } } @@ -1704,7 +1704,7 @@ private function exportDeploymentData(Func $func, array $deployment): void $responseHeaders ); - // content-length header was missing, file is less than max buffer size. + // content-length header missing, file is less than max buffer size if (!array_key_exists('content-length', $responseHeaders)) { $file = $this->call( 'GET', @@ -1739,7 +1739,7 @@ private function exportDeploymentData(Func $func, array $deployment): void $fileSize = $responseHeaders['content-length']; - if ($end > $fileSize - 1) { + if ($end >= $fileSize) { $end = $fileSize - 1; } @@ -1776,7 +1776,7 @@ private function exportDeploymentData(Func $func, array $deployment): void $start += Transfer::STORAGE_MAX_CHUNK_SIZE; $end += Transfer::STORAGE_MAX_CHUNK_SIZE; - if ($end > $fileSize) { + if ($end >= $fileSize) { $end = $fileSize - 1; } } @@ -1957,7 +1957,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void $fileSize = $responseHeaders['content-length']; - if ($end > $fileSize - 1) { + if ($end >= $fileSize) { $end = $fileSize - 1; } @@ -1990,7 +1990,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void $start += Transfer::STORAGE_MAX_CHUNK_SIZE; $end += Transfer::STORAGE_MAX_CHUNK_SIZE; - if ($end > $fileSize) { + if ($end >= $fileSize) { $end = $fileSize - 1; } }