PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.4
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.4
1.3.4 1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 All 30 releases
← All changes | includes/class-health.php +74 -0 1.3.21.3.4 View file →
@@ -407,8 +407,16 @@
407 407 ? 'Pretty permalinks active.'
408 408 : 'Set permalinks to anything other than "Plain" — page caching needs URL paths to key on.',
409 409 );
410 410
411 + // What is in front of the site, and what we are telling it. Extracted
412 + // so it can be exercised without paying for every other probe in
413 + // checks(); see edge_check().
414 + $edge_row = self::edge_check();
415 + if ( null !== $edge_row ) {
416 + $out[] = $edge_row;
417 + }
418 +
411 419 // Cache-poisoning Set-Cookie detection (issue #33): a plugin emitting
412 420 // Set-Cookie on anonymous pageviews forces CDN/edge BYPASS for all
413 421 // HTML (Cloudflare never caches a response carrying Set-Cookie). Probe
414 422 // is transient-throttled inside Cookie_Inspector, same pattern as the
@@ -570,8 +578,74 @@
570 578 * wp_get_schedules() lookup.
571 579 * @return array{id:string,tone:string,label:string,detail:string}|null Check
572 580 * row, or null when the rule doesn't apply (preloader off/manual).
573 581 */
582 + /**
583 + * What cache is in front of the site, and what we are telling it.
584 + *
585 + * Reported whether or not anything is currently being held back, because
586 + * the useful half is the caveat rather than the header. A Cloudflare
587 + * Cache Rule set to ignore origin headers overrides everything xSpeed
588 + * sends, and someone debugging "my cart page is still being cached"
589 + * needs telling that rather than left to discover it.
590 + *
591 + * Null when nothing was detected and nothing was switched off: there is
592 + * no news in "we looked and saw nothing", and a row saying so on every
593 + * ordinary single-server site would be noise in a panel people scan for
594 + * problems.
595 + *
596 + * @return array{id:string,tone:string,label:string,detail:string}|null
597 + */
598 + public static function edge_check(): ?array {
599 + $edge = Edge_Provider::detect();
600 +
601 + if ( Edge_Provider::is_off( $edge ) ) {
602 + return array(
603 + 'id' => 'edge_hold',
604 + 'tone' => self::WARN,
605 + 'label' => 'Edge cache not being told anything',
606 + 'detail' => 'xSpeed is set not to send cache headers to the CDN in front of this site, so first renders and bypassed pages can be stored at the edge. Set "Cache In Front Of This Site" back to automatic unless you are sending your own headers.',
607 + );
608 + }
609 +
610 + if ( Edge_Provider::NONE === $edge['confidence'] ) {
611 + return null;
612 + }
613 +
614 + $named = '' !== $edge['provider'] ? $edge['provider'] : 'a cache we could not identify';
615 +
616 + // A pin outranks detection by design, so nothing re-checks it on the
617 + // site's behalf — and it is the one answer that also reaches the
618 + // drop-in and the server rules. Comparing it against the request is
619 + // the only way a site that changed CDN ever finds out.
620 + $sniffed = Edge_Provider::sniffed();
621 + if ( in_array( $edge['source'], array( 'setting', 'constant', 'filter' ), true )
622 + && '' !== $sniffed['provider']
623 + && $sniffed['provider'] !== $edge['provider'] ) {
624 + return array(
625 + 'id' => 'edge_hold',
626 + 'tone' => self::WARN,
627 + 'label' => 'Edge cache setting looks out of date',
628 + 'detail' => sprintf(
629 + 'This request looks like %s, but the provider is pinned to %s. If the site moved, update it — the pinned answer is also baked into the drop-in and the server rules.',
630 + $sniffed['provider'],
631 + $named
632 + ),
633 + );
634 + }
635 +
636 + $caveat = 'cloudflare' === $edge['provider']
637 + ? ' A Cloudflare Cache Rule whose Edge TTL is "Ignore cache-control header and use this TTL" overrides this; use "Respect origin TTL" on that rule.'
638 + : '';
639 +
640 + return array(
641 + 'id' => 'edge_hold',
642 + 'tone' => self::OK,
643 + 'label' => 'Edge cache being told what not to store',
644 + 'detail' => sprintf( 'First renders, bypassed pages and mobile-split pages are marked do-not-store for %s.%s', $named, $caveat ),
645 + );
646 + }
647 +
574 648 public static function expiry_preload_check( int $expiry_hours, string $schedule, bool $preloader_enabled, ?int $interval_hours = null ): ?array {
575 649 if ( ! $preloader_enabled ) {
576 650 return null;
577 651 }