From 71b7990dda3d5c3ae84b8dc7b4e671a6e7099325 Mon Sep 17 00:00:00 2001 From: Riddhesh Sanghvi Date: Mon, 12 Oct 2026 10:18:15 +0530 Subject: [PATCH] fix(site): use a new file for every www check The www/non-www check wrote `check.html` into the webroot, curled it through the www name and deleted it. The site's nginx (easyengine/nginx) caches open files for 2 minutes (`open_file_cache ... valid 2m`), so a second check within 2 minutes got the first check's deleted file back and failed. This hit `ee site update --ssl=le` right after `ee site create`: no www redirect conf and no www name on the certificate. Self-signed updates hid it, as they count as wildcard. Each check now uses its own `ee-www-check-.html`, and a failed check logs the HTTP status and the final URL. --- src/helper/class-ee-site.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/helper/class-ee-site.php b/src/helper/class-ee-site.php index 505a395c..fd1c650c 100644 --- a/src/helper/class-ee-site.php +++ b/src/helper/class-ee-site.php @@ -1910,7 +1910,9 @@ protected function check_www_or_non_www_domain( $site_url, $site_path, $site_con $random_string = EE\Utils\random_password(); $successful = false; $extra_path = str_replace( '/var/www/htdocs', '', $site_container_path ); - $file_path = $site_path . '/app/htdocs' . $extra_path . '/check.html'; + // A new name per check: the site's nginx caches open files for 2 minutes (open_file_cache), so a reused name serves the previous check's file. + $check_file = 'ee-www-check-' . bin2hex( random_bytes( 8 ) ) . '.html'; + $file_path = $site_path . '/app/htdocs' . $extra_path . '/' . $check_file; // The site can write here: drop whatever is at the path so a planted symlink isn't followed, then create the file exclusively. if ( is_link( $file_path ) || is_file( $file_path ) ) { @@ -1934,19 +1936,24 @@ protected function check_www_or_non_www_domain( $site_url, $site_path, $site_con $site_url = 'www.' . $site_url; } - $site_url .= '/check.html'; + $site_url .= '/' . $check_file; $curl = curl_init(); curl_setopt( $curl, CURLOPT_URL, $site_url ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $curl, CURLOPT_HEADER, false ); - $data = curl_exec( $curl ); + $data = curl_exec( $curl ); + $http_code = curl_getinfo( $curl, CURLINFO_HTTP_CODE ); + $final_url = curl_getinfo( $curl, CURLINFO_EFFECTIVE_URL ); + $error = curl_error( $curl ); curl_close( $curl ); if ( ! empty( $data ) && $random_string === $data ) { $successful = true; EE::debug( "pointed for $site_url" ); + } else { + EE::debug( sprintf( 'www check failed for %s: HTTP %d from %s%s', $site_url, $http_code, $final_url, $error ? " ($error)" : '' ) ); } if ( file_exists( $file_path ) ) {