Skip to content

Skip oversized Link preload header in Optimization Detective#2572

Open
faisalahammad wants to merge 1 commit into
WordPress:trunkfrom
faisalahammad:fix/2304-oversized-link-header
Open

Skip oversized Link preload header in Optimization Detective#2572
faisalahammad wants to merge 1 commit into
WordPress:trunkfrom
faisalahammad:fix/2304-oversized-link-header

Conversation

@faisalahammad

Copy link
Copy Markdown

Summary

Fixes #2304

Image Prioritizer (via Optimization Detective) can generate a Link: rel=preload response header that gets too large when responsive images have long or non-ASCII filenames across multiple viewport breakpoints with different LCP images. Some reverse proxies (Nginx) reject the response with "upstream sent too big header", causing intermittent 502s for logged-in users.

Relevant technical choices

od_optimize_template_output_buffer() in optimization.php already sends both a Link response header and equivalent HTML <link> tags for every collected preload link, unconditionally. The HTML tags carry the same preload info, so the fix skips sending the header when it would exceed a length cap and just relies on the HTML tags in that case.

  • Added od_get_maximum_link_response_header_length(), mirroring the existing od_get_maximum_url_metric_size() pattern (filter od_link_response_header_max_length, default 4 KB, _doing_it_wrong() fallback on invalid values).
  • Guard added to the existing header() call in optimization.php; the append_head_html() call stays unconditional so preloading keeps working through HTML tags when the header is skipped.
  • Fix lives in Optimization Detective (not Image Prioritizer) since every extension that adds preload links funnels through this one call site.
  • Added doc entry for the new filter in docs/hooks.md.
  • Added tests for the new getter (default, filter override, invalid value) and for the HTML fallback always being present. Note: headers_sent() is always true in this repo's PHPUnit harness, so the actual header() call itself can't be asserted on in automated tests (this was already true before this change, nothing here regresses that).

Testing

Manual: page with responsive images across several breakpoints resolving to different LCP images with long filenames, logged in, uncached request — confirmed no single Link header exceeds the cap and <link rel="preload"> tags are still present in <head>. Verified the filter raises/lowers the cap as expected.

Automated: npm run test-php:optimization-detective (360 tests pass), composer lint:optimization-detective (clean), npm run phpstan (no errors).

Use of AI Tools

Used an AI coding assistant (Claude Code) to investigate the codebase, draft the implementation, tests, and docs, and to run the test/lint/static-analysis suite. I reviewed the change, ran the tests myself, and take responsibility for the code.

- Add od_get_maximum_link_response_header_length() with filter
  od_link_response_header_max_length (default 4KB)
- Skip sending the Link response header when it would exceed the
  limit, falling back to the existing HTML link tag output
- Add tests covering the new getter and the HTML fallback

Some reverse proxies fail requests with an oversized response header,
which can happen when responsive images have long or non-ASCII
filenames across multiple viewport breakpoints. The HTML link tags
already carry the same preload info, so skipping the header when it
is too large keeps the request from failing without losing preload
behavior.

Fixes WordPress#2304
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: faisalahammad <faisalahammad@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: ttwrpz <sigmarubyz@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added the [Plugin] Optimization Detective Issues for the Optimization Detective plugin label Jul 5, 2026
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.41%. Comparing base (8d70987) to head (d488736).

Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #2572      +/-   ##
==========================================
+ Coverage   70.35%   70.41%   +0.05%     
==========================================
  Files          91       91              
  Lines        7867     7882      +15     
==========================================
+ Hits         5535     5550      +15     
  Misses       2332     2332              
Flag Coverage Δ
multisite 70.41% <100.00%> (+0.05%) ⬆️
single 35.27% <81.25%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Plugin] Optimization Detective Issues for the Optimization Detective plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image Prioritizer causes 502 Bad Gateway due to oversized Link response headers (Nginx reverse proxy)

1 participant