Skip to content

refactor(remote-config): Support RC Container Format for remote config request, remove stale implementation temporarily#3607

Merged
tonidero merged 10 commits into
mainfrom
rc-format-binary-remote-config
Jun 18, 2026
Merged

refactor(remote-config): Support RC Container Format for remote config request, remove stale implementation temporarily#3607
tonidero merged 10 commits into
mainfrom
rc-format-binary-remote-config

Conversation

@tonidero

@tonidero tonidero commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Stacked on #3534.

What

  • Introduces HTTPResult.Payload (Text / RCFormat) so the HTTP layer can carry raw bytes, with a payloadText accessor. Pure refactor; text call sites are unchanged.
  • GetRemoteConfig now requests the RC Container Format (Accept: application/x-rc-format) and parses the response into an RCContainer. RCFormat responses bypass the ETag cache.
  • Removes unused previous remote config implementation files after modifications in the model format.

This PR doesn't change any behavior, but adds initial support for RC Container format requests.


Note

Medium Risk
Touches shared HTTP/ETag behavior and deletes the remote-config refresh/download path, so config-related behavior is incomplete until replaced; JSON endpoints are largely unchanged via payloadText.

Overview
Refactors the HTTP layer so responses can be text (JSON) or raw RC Container bytes, via HTTPResult.Payload and payloadText for existing JSON call sites.

GetRemoteConfig now negotiates Accept: application/x-rc-format, skips ETag caching, treats 204 as “no update” (null RCContainer), and parses successful bodies with RCContainer.parse. HTTPClient reads bodies as bytes, sets RC-format headers only when endpoint.expectsRCFormatResponse, and bypasses the ETag manager for those endpoints.

The prior JSON-based remote config implementation is removed (RemoteConfigManager, TopicFetcher, RemoteConfigResponse, disk cache, and related tests) until a follow-up wires the new container format end-to-end.

Reviewed by Cursor Bugbot for commit 62f6bea. Bugbot is set up for automated code reviews on this repo. Configure here.

@tonidero tonidero changed the title Support RC Container Format for remote config request refactor(remote-config): Support RC Container Format for remote config request Jun 16, 2026
@tonidero tonidero force-pushed the poc/rc-container-format-deserializer branch from b0b0c57 to a9c2140 Compare June 16, 2026 11:08
@tonidero tonidero force-pushed the rc-format-binary-remote-config branch from 4cd4c47 to 2538600 Compare June 16, 2026 11:08
@tonidero tonidero force-pushed the poc/rc-container-format-deserializer branch from a9c2140 to 7b9d434 Compare June 16, 2026 14:40
@tonidero tonidero force-pushed the rc-format-binary-remote-config branch from 2538600 to 7ea7a07 Compare June 16, 2026 14:40
name = "get_remote_config",
) {
override fun getPath(useFallback: Boolean) = pathTemplate
override val expectsBinaryResponse: Boolean = true

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This endpoint is currently unused so not a problem to change it.

@tonidero tonidero marked this pull request as ready for review June 16, 2026 15:15
@tonidero tonidero requested a review from a team as a code owner June 16, 2026 15:15

@ajpallares ajpallares left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking good! I have some comments!
Thanks for making the effort to split these into smaller PRs. Really appreciated 🙏

RCHTTPStatusCodes.isSuccessful(responseCode)
) {
verifyResponse(path, connection, payload, nonce, postFieldsToSignHeader)
verifyResponse(path, connection, payloadText, nonce, postFieldsToSignHeader)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think right now GetRemoteConfig doesn't support signature verification, but if it ever does, couldn't this (passing null / empty string to verify) be a problem?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's actually done in this follow-up PR, and yeah, so it has a different method to handle this case which will use only the main config hash to simplify it

Comment thread purchases/src/main/kotlin/com/revenuecat/purchases/common/Backend.kt Outdated
Comment thread purchases/src/main/kotlin/com/revenuecat/purchases/common/HTTPClient.kt Outdated
Comment thread purchases/src/main/kotlin/com/revenuecat/purchases/common/HTTPClient.kt Outdated
endpoint: Endpoint,
): Map<String, String> {
return mapOf(
"Content-Type" to "application/json",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it okay to still send "Content-Type" to "application/json" for the remote config endpoint?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a good question... need to check with the backend folks since I haven't been able to test this against that yet (code is unused right now though)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually, I think this is right. Content-Type is supposed to be the format of the request, which will indeed still be plain json. Accept determined the accepted formats for the response, so I don't think this should be an issue.

@tonidero tonidero force-pushed the rc-format-binary-remote-config branch from 7ea7a07 to 678860e Compare June 17, 2026 13:05
@tonidero tonidero force-pushed the poc/rc-container-format-deserializer branch from 9cd9f13 to 4288db2 Compare June 17, 2026 13:05
@emerge-tools

emerge-tools Bot commented Jun 17, 2026

Copy link
Copy Markdown

📸 Snapshot Test

593 unchanged

Name Added Removed Modified Renamed Unchanged Errored Approval
TestPurchasesUIAndroidCompatibility
com.revenuecat.testpurchasesuiandroidcompatibility
0 0 0 0 335 0 N/A
TestPurchasesUIAndroidCompatibility Paparazzi
com.revenuecat.testpurchasesuiandroidcompatibility.paparazzi
0 0 0 0 258 0 N/A

🛸 Powered by Emerge Tools

Comment thread purchases/src/main/kotlin/com/revenuecat/purchases/common/networking/Endpoint.kt Outdated
Base automatically changed from poc/rc-container-format-deserializer to main June 18, 2026 09:45
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.70588% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.30%. Comparing base (4ade8e4) to head (62f6bea).

Files with missing lines Patch % Lines
...tlin/com/revenuecat/purchases/common/HTTPClient.kt 75.55% 8 Missing and 3 partials ⚠️
...venuecat/purchases/common/networking/HTTPResult.kt 89.47% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3607      +/-   ##
==========================================
- Coverage   80.46%   80.30%   -0.17%     
==========================================
  Files         382      378       -4     
  Lines       15594    15475     -119     
  Branches     2166     2147      -19     
==========================================
- Hits        12548    12427     -121     
- Misses       2172     2189      +17     
+ Partials      874      859      -15     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

tonidero and others added 2 commits June 18, 2026 12:01
Introduces HTTPResult.Payload (Text/Binary) so the HTTP layer can carry raw
bytes, and switches GetRemoteConfig to request the binary RC Container Format
(Accept: application/x-rc-format), parsing the response into an RCContainer.
Binary responses bypass the ETag cache. Signature verification for the endpoint
remains disabled, unchanged from before; it is enabled in the follow-up PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tonidero tonidero force-pushed the rc-format-binary-remote-config branch from 42d3db7 to 84b96ec Compare June 18, 2026 10:02
The RC Container Format migration left the previous RemoteConfigResponse-based
processing commented out in RemoteConfigManager and kept several now-unused files
alive as WIP placeholders. These are removed (rather than commented out) here so the
intermediate state never lands; the reworked manager/disk-cache are reintroduced in
later PRs in the stack. WeightedSource is kept as it survives the rework.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tonidero tonidero changed the title refactor(remote-config): Support RC Container Format for remote config request refactor(remote-config): Support RC Container Format for remote config request, remove stale implementation temporarily Jun 18, 2026
The HTTPResult.Payload.Binary variant is only ever used for the RC Container
Format response. Rename it to RCFormat to describe its purpose rather than its
encoding, consistent with the endpoint flag expectsRCFormatResponse. Updates
the type plus associated comments, KDoc, log strings, error messages, and test
names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tonidero tonidero requested review from a team and rickvdl June 18, 2026 11:00

@rickvdl rickvdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome work, just one remaining question 💪

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread purchases/src/main/kotlin/com/revenuecat/purchases/common/HTTPClient.kt Outdated
tonidero and others added 2 commits June 18, 2026 15:27
A 204 from the remote config endpoint can yield no readable body stream on
some Android devices, which surfaced as a network IOException instead of
reaching the 204 handler. Treat a missing body on a 204 as empty bytes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5052c31. Configure here.

@tonidero tonidero force-pushed the rc-format-binary-remote-config branch from 5052c31 to 3362ea2 Compare June 18, 2026 13:54
@tonidero tonidero enabled auto-merge June 18, 2026 15:04
@tonidero tonidero added this pull request to the merge queue Jun 18, 2026
Merged via the queue into main with commit 5487b43 Jun 18, 2026
38 checks passed
@tonidero tonidero deleted the rc-format-binary-remote-config branch June 18, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants