Skip to content

Tolerate URL normalization differences in cache lookups#1317

Merged
crazytonyli merged 3 commits into
trunkfrom
bugfix/url-comparison
May 4, 2026
Merged

Tolerate URL normalization differences in cache lookups#1317
crazytonyli merged 3 commits into
trunkfrom
bugfix/url-comparison

Conversation

@crazytonyli
Copy link
Copy Markdown
Contributor

Description

Two integration tests in wp_mobile_integration_tests/tests/test_remove_site.rs panicked with site should exist. The root cause was an interaction between two PRs that landed in sequence on trunk:

Neither PR's CI saw the combination. Post-merge on trunk, the cache stored the normalized form (http://localhost/) while the tests still queried the raw form (http://localhost), and select_self_hosted_site_by_url's bare WHERE url = ? lookup returned None. The trailing-slash tolerance from url_candidates had never been wired into the read path.

Changes

Register a urls_eq(a, b) SQLite UDF that compares URLs via ParsedUrl parsing, replace WHERE url = ? with WHERE urls_eq(url, ?) in select_self_hosted_site_by_url, and remove url_candidates. Every URL-keyed read now uses a single tolerant mechanism, so historical caches stored in any normalization shape continue to match.

Test plan

CI green.

Changelog

  • I've added an entry to CHANGELOG.md under ## [Unreleased], using the Keep a Changelog categories (Added, Changed, Deprecated, Removed, Fixed, Security). Prefix breaking changes with **BREAKING:**.

Register a `urls_eq` SQLite scalar function that compares two URL
strings via `ParsedUrl` parsing (with raw-string fast path) and use it
in `WHERE urls_eq(url, ?)` for `self_hosted_sites.url` reads. Lookups
now match the same site whether it was stored as `http://localhost`
or `http://localhost/`, which fixes the trunk integration-test break
in `test_remove_site.rs` and removes the latent risk of duplicate rows
on devices upgrading across PR #1239.

Replaces the narrower `url_candidates` workaround (and the
`delete_self_hosted_site_by_url(&[String])` overload that consumed it),
so every URL-keyed read goes through one mechanism.
`register_url_functions` can fail at the SQLite layer; switch the
impl from `From<Connection>` to `TryFrom<Connection>` so callers
surface the error as `SqliteDbError` rather than panic. The four
existing call sites are unit-test setup, which now `.expect(...)`
the result.
@crazytonyli crazytonyli requested review from jkmassel and oguzkocer May 4, 2026 22:01
@crazytonyli crazytonyli changed the title Bugfix/url comparison Tolerate URL normalization differences in cache lookups May 4, 2026
@oguzkocer
Copy link
Copy Markdown
Contributor

I am reviewing this as-is, but I wonder if it'd be better to handle the existing data through a migration and normalize the insert/look-up instead of trying to work around it.

@crazytonyli
Copy link
Copy Markdown
Contributor Author

My main concern is that we'll have new code to insert random strings as "site url". To ensure the stored url exactly matches ParsedUrl, we'd need to do something like this for each insertion/update:

// normalized the `url_str` input to another url string.
let url = ParsedUrl.parse(url_str) // TODO: error handling needed, even though 99.99% time we'll insert legal url strings.
let normalized = url.to_str()

sqlite.exec("INSERT ... VALUE (?)", noramlized)

I don't like this approach because:

  1. We may need to surface the url parsing error to the function API. That introduce unnecessary noises, when the url input is almost certain a legit url.
  2. It'd be easier to remember (or read/write) the new urls_eq function than the url parsing dance.

@wpmobilebot
Copy link
Copy Markdown
Collaborator

XCFramework Build

This PR's XCFramework is available for testing. Add to your Package.swift:

.package(url: "https://github.com/automattic/wordpress-rs", branch: "pr-build/1317")

Built from 84e0f98

@crazytonyli crazytonyli merged commit 1e59f79 into trunk May 4, 2026
34 checks passed
@crazytonyli crazytonyli deleted the bugfix/url-comparison branch May 4, 2026 22:43
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.

3 participants