Fix mixed content errors from malformed CDN URLs in protocol-relative and triple-slash URL handling#1049
Conversation
…ation in build_url() Agent-Logs-Url: https://github.com/Codeinwp/optimole-wp/sessions/b12c03d6-d980-4909-8199-8aafbe58a311 Co-authored-by: kushh23 <110405452+kushh23@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes malformed Optimole CDN URLs that could lead to HTTPS→HTTP redirects (mixed content) by correcting protocol handling in two normalization paths.
Changes:
- Fixes
add_schema()ternary/concatenation precedence so protocol-relative URLs retain the//...portion when SSL is on. - Normalizes triple-slash (
///host/path) and protocol-relative (//host/path) inputs inbuild_url()to a well-formedhttp(s)://host/pathform.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
inc/url_replacer.php |
Ensures protocol-relative/triple-slash URLs are rebuilt with a valid http(s):// prefix. |
inc/traits/normalizer.php |
Fixes schema-prepending logic so SSL correctly yields https://... for //... URLs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot lets add those unit tests which were discovered in code review |
…ple-slash URL normalization Agent-Logs-Url: https://github.com/Codeinwp/optimole-wp/sessions/0b947f08-2140-4d1b-9330-9381b891257a Co-authored-by: kushh23 <110405452+kushh23@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Codeinwp/optimole-wp/sessions/0b947f08-2140-4d1b-9330-9381b891257a Co-authored-by: kushh23 <110405452+kushh23@users.noreply.github.com>
Added in commit 9e725b8:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…re can_replace_url() and test build_url() directly Agent-Logs-Url: https://github.com/Codeinwp/optimole-wp/sessions/8939ca95-d282-4d7f-96c9-a37fb5fc50ec Co-authored-by: kushh23 <110405452+kushh23@users.noreply.github.com>
add_schema()ininc/traits/normalizer.phpbuild_url()ininc/url_replacer.phptest_add_schema_non_ssl(),test_add_schema_ssl(),test_add_schema_already_schemed()totests/test-generic.php//////scheme normalization beforecan_replace_url()soparse_url()succeeds on protocol-relative URLstest_build_url_normalizes_triple_slash()— testsbuild_url()directly with both//and///inputsassertStringNotEqualsintest_add_schema_ssl()Original prompt
Summary
This PR fixes two bugs in the Optimole plugin that together cause mixed content errors and broken images in AJAX contexts (e.g., WooCommerce mini-cart loaded via custom
admin-ajaxactions). Reported by a user on windmeile.com. See issue: #1048Bug 1: Operator precedence error in
add_schema()—inc/traits/normalizer.phpFile:
inc/traits/normalizer.phpMethod:
add_schema()Lines: ~374–376
Current (buggy) code:
Problem:
Due to PHP operator precedence,
.(concatenation) binds tighter than?:(ternary). So the code is actually evaluated as:When
is_ssl()returnstrue,$schema_urlis set to the bare string'https:'instead of'https://…'. The//part is lost entirely.Fix:
Bug 2: Triple-slash URLs (
///host/path) not normalized inbuild_url()—inc/url_replacer.phpFile:
inc/url_replacer.phpMethod:
build_url()Lines: ~156–158
Current (buggy) code:
Problem:
When a URL has three leading slashes (
///windmeile.com/wp-content/uploads/…),substr($url, 0, 2) === '//'is stilltrue, so the code prependshttps:to producehttps:///windmeile.com/…— a malformed URL with three slashes after the colon. This malformed URL gets embedded into the Optimole CDN URL path. The CDN backend cannot properly resolve this scheme-less/invalid origin URL and falls back to a302 Location: http://…redirect, causing the browser to see a mixed content error (HTTPS page → HTTP redirect target).Fix:
Strip all leading slashes before rebuilding the URL with the correct scheme and
://:Expected outcome after fix
//host/path) and triple-slash URLs (///host/path) are both correctly normalized tohttps://host/path(orhttp://on non-SSL) before being passed to the Optimole SDK and CDN.add_schema()helper correctly prependshttps:+ the original//…string instead of discarding it.///embedded origin paths.302 Location: http://…fallback redirects causing mixed content errors.Files to change
inc/traits/normalizer.php— Fixadd_schema()operator precedence (line ~375)inc/url_replacer.php— Fix triple-slash URL normalization inbuild_url()(lines ~156–158)Related
302 Location: http://…The following is the prior conversation context from the user's chat exploration (may be truncated):
User: check if this is a issue with optimole or not
find the root cause of the mixed content issue on our WooCommerce store (windmeile.com) related to Optimole image URLs generated in an AJAX mini-cart (theme uses a custom admin-ajax action uncode_ajax_add_to_cart). Here is the summary: What happend
The page is loaded via HTTPS.
The mini-cart (loaded via AJAX) contains Optimole CDN URLs like: src="//.i.optimole.com/...///windmeile.com/wp-content/uploads/...png" (CDN URL is protocol-relative //… and the embedded origin part is scheme-less: ///windmeile.com/...)
When the browser requests the CDN URL over HTTPS, Optimole returns a redirect:
Response: 302 Found
Header: Location: http://windmeile.com/wp-content/uploads/...
This produces a browser mixed content error (HTTPS page → resource is redirected to HTTP) and breaks the mini-cart thumbnails. Debugging results (confirmed on our side)
WordPress correctly detects SSL even during the AJAX call (is_ssl() = true, HTTPS=on, SERVER_PORT=443, X-Forwarded-Proto=https).
We verified that the input URL passed into Optimole processing is already HTTPS: https://windmeile.com/wp-content/uploads/...
The problem is reproducible by directly opening the Optimole CDN URL in a new browser tab: it still responds with 302 Location: http://....
If we manually request the http://windmeile.com/... URL, our server redirects it to HTTPS. However, the browser blocks it anyway because the chain starts with an insecure HTTP redirect target.
Conclusion: it appears Optimole cannot properly handle scheme-less embedded origin URLs (///windmeile.com/...) and falls back to an HTTP redirect target instead of HT...
This pull request was created from Copilot chat.