Skip to content

fix: deployment download bugs and range clamping in Appwrite source#152

Merged
abnegate merged 6 commits intomainfrom
fix-kebab-case-site
Feb 25, 2026
Merged

fix: deployment download bugs and range clamping in Appwrite source#152
abnegate merged 6 commits intomainfrom
fix-kebab-case-site

Conversation

@premtsd-code
Copy link
Contributor

@premtsd-code premtsd-code commented Feb 24, 2026

Summary

  • Use lowercase content-length header key — Target::call() lowercases all response headers via strtolower(), so Content-Length never matched
  • Use strlen instead of mb_strlen for binary deployment data — mb_strlen misinterprets gzip bytes as UTF-8 characters, returning incorrect size
  • Use $end >= $fileSize for range clamping — server rejects Range requests where $end >= $size, the previous $end > $fileSize missed the edge case where $end == $fileSize

Summary by CodeRabbit

  • Bug Fixes

    • Fixed inconsistent boundary checking in file downloads and exports.
    • Improved handling of missing HTTP headers during file transfers.
  • Refactor

    • Standardized header processing and download logic across export operations for increased reliability.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Important

Review skipped

This PR was authored by the user configured for CodeRabbit reviews. By default, CodeRabbit skips reviewing PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Removed the normalization that lowercased computed resource identifiers in src/Migration/Transfer.php so computedResources now preserves original casing. Updated public constant string values in src/Migration/Resource.php from kebab-case to camelCase (site-deployment → siteDeployment, site-variable → siteVariable, environment-variable → environmentVariable). In src/Migration/Sources/Appwrite.php: replaced Content-Length checks with content-length, switched mb_strlen to strlen for downloaded size calculations, and added clamping of end offsets to fileSize - 1 where content-length is available. No other control-flow changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title describes deployment download bugs, but the actual primary change is converting multi-word resource type values from kebab-case to camelCase. Update the title to reflect the main objective: 'fix: use camelCase for multi-word resource type values' or similar, as this is the core change driving the modifications across multiple files.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Migration/Resource.php`:
- Around line 55-61: The constants in Resource (TYPE_SITE_DEPLOYMENT,
TYPE_SITE_VARIABLE, TYPE_HASH, TYPE_ENVIRONMENT_VARIABLE) use camelCase string
values but must be snake_case; change their assigned values to
'site_deployment', 'site_variable', 'hash' (keep as-is if already correct), and
'environment_variable' respectively, and update any consuming code/tests to use
the new snake_case string values if they reference the literal strings instead
of the constants.
- Around line 55-61: The public constants TYPE_SITE_DEPLOYMENT,
TYPE_SITE_VARIABLE, TYPE_HASH, and TYPE_ENVIRONMENT_VARIABLE in Resource.php
were changed from kebab-case to camelCase which will break external consumers
and the strtolower() call in Transfer.php (around line 235) will produce
unexpected values; restore the original kebab-case literal values
('site-deployment', 'site-variable', 'hash', 'environment-variable') in
Resource.php OR alternatively update the normalization in Transfer.php to
explicitly convert camelCase to kebab-case (e.g., insert a camelCase->kebab-case
transformation before strtolower) so external serialized outputs remain
unchanged.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8b2fb8 and 79cab8e.

📒 Files selected for processing (1)
  • src/Migration/Resource.php

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/Migration/Resource.php (1)

55-61: ⚠️ Potential issue | 🔴 Critical

Constants still use camelCase — PR objective requires snake_case.

The three changed values are still camelCase ('siteDeployment', 'siteVariable', 'environmentVariable'), contradicting the PR's own stated objective:

"Updated Resource.php type constants: site-deploymentsite_deployment, site-variablesite_variable, environment-variableenvironment_variable."

The strtolower() concern from the earlier review is now moot since Transfer.php removed that normalization, but the intended literal values in this file are still wrong.

🐛 Proposed fix: align values with the PR's stated snake_case objective
-    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_ENVIRONMENT_VARIABLE = 'environmentVariable';
+    public const TYPE_ENVIRONMENT_VARIABLE = 'environment_variable';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Migration/Resource.php` around lines 55 - 61, The type constants in
Resource.php still use camelCase values; update the constant values for
TYPE_SITE_DEPLOYMENT, TYPE_SITE_VARIABLE, and TYPE_ENVIRONMENT_VARIABLE to use
snake_case literals ('site_deployment', 'site_variable', 'environment_variable')
so they match the PR objective and other code expecting those exact strings;
leave the constant names unchanged and only change the right-hand string
literals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/Migration/Resource.php`:
- Around line 55-61: The type constants in Resource.php still use camelCase
values; update the constant values for TYPE_SITE_DEPLOYMENT, TYPE_SITE_VARIABLE,
and TYPE_ENVIRONMENT_VARIABLE to use snake_case literals ('site_deployment',
'site_variable', 'environment_variable') so they match the PR objective and
other code expecting those exact strings; leave the constant names unchanged and
only change the right-hand string literals.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8260df and 987d11c.

📒 Files selected for processing (1)
  • src/Migration/Resource.php

@premtsd-code premtsd-code changed the title fix: use snake_case for multi-word resource type constants fix: use camelCase for multi-word resource type values Feb 25, 2026
…eploymentData

- 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)
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/Migration/Sources/Appwrite.php (1)

1927-1927: Same header-casing concern as in exportDeploymentData.

This has the same dependency on $this->call() returning lowercase header keys. See the earlier comment on line 1708.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Migration/Sources/Appwrite.php` at line 1927, The check for
'content-length' assumes $responseHeaders keys are lowercase (same issue as in
exportDeploymentData); update the handling in the code path that uses
$responseHeaders (the conditional around array_key_exists('content-length',
$responseHeaders)) to perform a case-insensitive header lookup or normalize
header keys (e.g., map keys to lowercase before checking) so the check works
regardless of $this->call()'s header casing; ensure you apply the same
normalization approach used/fixed in exportDeploymentData to keep behavior
consistent.
🧹 Nitpick comments (2)
src/Migration/Sources/Appwrite.php (2)

1740-1744: Good addition of initial end-offset clamping, but note inconsistency with loop clamping.

The new guard at lines 1742-1744 correctly uses $fileSize - 1, however the existing loop guard at line 1779 uses $end > $fileSize (without - 1). This means if $end equals exactly $fileSize after incrementing, it won't be clamped, producing an out-of-range byte request (bytes=start-fileSize where valid indices are 0 to fileSize-1).

Consider aligning the loop guard for consistency:

♻️ Align loop clamping with initial clamping
-            if ($end > $fileSize) {
+            if ($end > $fileSize - 1) {
                 $end = $fileSize - 1;
             }

Also applies to: 1779-1781

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Migration/Sources/Appwrite.php` around lines 1740 - 1744, The loop that
re-clamps $end in Appwrite.php is inconsistent with the initial clamp: change
the loop guard that currently compares `$end > $fileSize` to use `$end >
$fileSize - 1` so `$end` is never set to `fileSize` (out of range); update the
loop logic that increments and clamps `$end` (refer to the `$end` variable and
the loop block around the existing guard) to match the initial clamping behavior
and ensure all byte-range requests use indices 0..$fileSize-1.

1958-1962: Same loop clamping inconsistency as exportDeploymentData.

The initial guard correctly uses $fileSize - 1 but the loop at line 1993 uses $end > $fileSize. Apply the same fix here for consistency:

♻️ Align loop clamping
-            if ($end > $fileSize) {
+            if ($end > $fileSize - 1) {
                 $end = $fileSize - 1;
             }

Also applies to: 1993-1995

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Migration/Sources/Appwrite.php` around lines 1958 - 1962, The loop
clamping is inconsistent: after reading $fileSize from $responseHeaders the
initial guard sets $end = $fileSize - 1 but the later loop compares using $end >
$fileSize; locate the loop that uses the $end variable in this class (same area
as exportDeploymentData) and change the condition to compare against $fileSize -
1 (i.e., use $end > $fileSize - 1) so both the initial guard and the loop use
the same off-by-one logic for $fileSize and $end.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/Migration/Sources/Appwrite.php`:
- Line 1927: The check for 'content-length' assumes $responseHeaders keys are
lowercase (same issue as in exportDeploymentData); update the handling in the
code path that uses $responseHeaders (the conditional around
array_key_exists('content-length', $responseHeaders)) to perform a
case-insensitive header lookup or normalize header keys (e.g., map keys to
lowercase before checking) so the check works regardless of $this->call()'s
header casing; ensure you apply the same normalization approach used/fixed in
exportDeploymentData to keep behavior consistent.

---

Nitpick comments:
In `@src/Migration/Sources/Appwrite.php`:
- Around line 1740-1744: The loop that re-clamps $end in Appwrite.php is
inconsistent with the initial clamp: change the loop guard that currently
compares `$end > $fileSize` to use `$end > $fileSize - 1` so `$end` is never set
to `fileSize` (out of range); update the loop logic that increments and clamps
`$end` (refer to the `$end` variable and the loop block around the existing
guard) to match the initial clamping behavior and ensure all byte-range requests
use indices 0..$fileSize-1.
- Around line 1958-1962: The loop clamping is inconsistent: after reading
$fileSize from $responseHeaders the initial guard sets $end = $fileSize - 1 but
the later loop compares using $end > $fileSize; locate the loop that uses the
$end variable in this class (same area as exportDeploymentData) and change the
condition to compare against $fileSize - 1 (i.e., use $end > $fileSize - 1) so
both the initial guard and the loop use the same off-by-one logic for $fileSize
and $end.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 987d11c and 8b1b42d.

📒 Files selected for processing (1)
  • src/Migration/Sources/Appwrite.php

@premtsd-code premtsd-code changed the title fix: use camelCase for multi-word resource type values fix: deployment download bugs in exportDeploymentData and exportSiteDeploymentData Feb 25, 2026
@premtsd-code premtsd-code changed the title fix: deployment download bugs in exportDeploymentData and exportSiteDeploymentData fix: deployment download bugs and range clamping in Appwrite source Feb 25, 2026
@abnegate abnegate merged commit 037bf4b into main Feb 25, 2026
4 checks passed
@abnegate abnegate deleted the fix-kebab-case-site branch February 25, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants