| @@ -389,9 +389,9 @@ | ||
| 389 | 389 | // lifetime, and this tree is served without PHP so nothing else |
| 390 | 390 | // can enforce it. A site caching for a week would otherwise hand |
| 391 | 391 | // out a dead nonce for six and a half days of it, breaking every |
| 392 | 392 | // anonymous form on the page. |
| 393 | - $expires_file = dirname( $path ) . '/.xspeed-expires'; | |
| 393 | + $expires_file = dirname( $path ) . '/' . Cache::EXPIRES_MARKER; | |
| 394 | 394 | // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- sidecar read on a cron sweep; WP_Filesystem is not loaded here. |
| 395 | 395 | $expires = is_readable( $expires_file ) ? (int) @file_get_contents( $expires_file ) : 0; // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- file may vanish between the check and the read. |
| 396 | 396 | if ( $expires > 0 ) { |
| 397 | 397 | $mtime = @filemtime( $path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- false is handled below. |
| @@ -519,29 +519,14 @@ | ||
| 519 | 519 | } |
| 520 | 520 | |
| 521 | 521 | /** |
| 522 | 522 | * Delete a cache entry and every sibling that only exists because of it, |
| 523 | - * so the sweep never creates the orphans it is there to remove: | |
| 524 | - * | |
| 525 | - * <md5>.html → <md5>.meta, <md5>.html.br | |
| 526 | - * index.html → index.html.br | |
| 527 | - * <key>.css/js → (none) | |
| 523 | + * so the sweep never creates the orphans it is there to remove. | |
| 528 | 524 | */ |
| 529 | 525 | private static function delete_entry( string $path ): void { |
| 530 | 526 | wp_delete_file( $path ); |
| 527 | + self::delete_siblings( $path ); | |
| 531 | 528 | |
| 532 | - $br = $path . '.br'; | |
| 533 | - if ( file_exists( $br ) ) { | |
| 534 | - wp_delete_file( $br ); | |
| 535 | - } | |
| 536 | - | |
| 537 | - if ( '.html' === substr( $path, -5 ) ) { | |
| 538 | - $meta = substr( $path, 0, -5 ) . '.meta'; | |
| 539 | - if ( file_exists( $meta ) ) { | |
| 540 | - wp_delete_file( $meta ); | |
| 541 | - } | |
| 542 | - } | |
| 543 | - | |
| 544 | 529 | // Deleting an asset and invalidating the pages that embed it are ONE |
| 545 | 530 | // operation, so the two caches can never disagree. is_referenced() |
| 546 | 531 | // already keeps a linked asset alive, so this is the belt to that |
| 547 | 532 | // braces: it covers the races the index cannot see — a page written |
| @@ -554,8 +539,34 @@ | ||
| 554 | 539 | } |
| 555 | 540 | } |
| 556 | 541 | |
| 557 | 542 | /** |
| 543 | + * The files that exist only because of $path: | |
| 544 | + * | |
| 545 | + * <md5>.html → <md5>.meta, <md5>.html.br, <md5>.html.br.size | |
| 546 | + * index.html → index.html.br, index.html.br.size, the expires marker | |
| 547 | + * <key>.css/js → its .br and .br.size, if any | |
| 548 | + * | |
| 549 | + * The marker and the size record were missed once, which left every | |
| 550 | + * nonce page's folder non-empty so prune_empty_dirs() could never remove | |
| 551 | + * it (#636). | |
| 552 | + */ | |
| 553 | + private static function delete_siblings( string $path ): void { | |
| 554 | + $siblings = array( $path . '.br', $path . '.br.size' ); | |
| 555 | + if ( '.html' === substr( $path, -5 ) ) { | |
| 556 | + $siblings[] = substr( $path, 0, -5 ) . '.meta'; | |
| 557 | + } | |
| 558 | + if ( 'index.html' === basename( $path ) ) { | |
| 559 | + $siblings[] = dirname( $path ) . '/' . Cache::EXPIRES_MARKER; | |
| 560 | + } | |
| 561 | + foreach ( $siblings as $sibling ) { | |
| 562 | + if ( file_exists( $sibling ) ) { | |
| 563 | + wp_delete_file( $sibling ); | |
| 564 | + } | |
| 565 | + } | |
| 566 | + } | |
| 567 | + | |
| 568 | + /** | |
| 558 | 569 | * Remove every cached page that links to the given asset. |
| 559 | 570 | * |
| 560 | 571 | * Walks both trees: the static one is served by nginx without PHP, so a |
| 561 | 572 | * page left there keeps serving the dead link no matter what the flat |
| @@ -583,13 +594,9 @@ | ||
| 583 | 594 | continue; |
| 584 | 595 | } |
| 585 | 596 | |
| 586 | 597 | wp_delete_file( $file ); |
| 587 | - foreach ( array( $file . '.br', substr( $file, 0, -5 ) . '.meta' ) as $sibling ) { | |
| 588 | - if ( file_exists( $sibling ) ) { | |
| 589 | - wp_delete_file( $sibling ); | |
| 590 | - } | |
| 591 | - } | |
| 598 | + self::delete_siblings( $file ); | |
| 592 | 599 | } |
| 593 | 600 | } |
| 594 | 601 | } |
| 595 | 602 | |