diff --git a/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php b/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php index 2787428a20..52468cab5a 100644 --- a/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php +++ b/src/Appwrite/Platform/Modules/Health/Http/Health/Storage/Get.php @@ -65,12 +65,27 @@ class Get extends Action throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); } - if ($device->read($filePath) !== 'test') { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); - } - - if (!$device->delete($filePath)) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); + $readError = null; + try { + if ($device->read($filePath) !== 'test') { + $readError = new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); + } + } catch (\Throwable $e) { + $readError = $e; + } finally { + // Always attempt to clean up test file + if (!$device->delete($filePath)) { + if ($readError !== null) { + // If read already failed, wrap delete error but preserve original + \error_log('Failed deleting test file from ' . $device->getRoot() . ' during read error recovery'); + } else { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); + } + } + // Re-throw read error if it occurred + if ($readError !== null) { + throw $readError; + } } } diff --git a/src/Appwrite/Platform/Modules/Health/Http/Health/Time/Get.php b/src/Appwrite/Platform/Modules/Health/Http/Health/Time/Get.php index 3636515cb0..b79553321f 100644 --- a/src/Appwrite/Platform/Modules/Health/Http/Health/Time/Get.php +++ b/src/Appwrite/Platform/Modules/Health/Http/Health/Time/Get.php @@ -54,30 +54,54 @@ class Get extends Action $sock = \socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); - \socket_connect($sock, $host, 123); - - $msg = "\010" . \str_repeat("\0", 47); - - \socket_send($sock, $msg, \strlen($msg), 0); - - \socket_recv($sock, $recv, 48, MSG_WAITALL); - \socket_close($sock); - - $data = \unpack('N12', $recv); - $timestamp = \sprintf('%u', $data[9]); - - $timestamp -= 2208988800; - - $diff = ($timestamp - \time()); - - if ($diff > $gap || $diff < ($gap * -1)) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Server time gaps detected'); + if ($sock === false) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to create socket: ' . \socket_strerror(\socket_last_error())); } - $response->dynamic(new Document([ - 'remoteTime' => $timestamp, - 'localTime' => \time(), - 'diff' => $diff, - ]), Response::MODEL_HEALTH_TIME); + try { + if (!\socket_connect($sock, $host, 123)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to connect to time server: ' . \socket_strerror(\socket_last_error($sock))); + } + + // Set receive timeout to prevent hanging + if (!\socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0])) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to set socket timeout: ' . \socket_strerror(\socket_last_error($sock))); + } + + $msg = "\010" . \str_repeat("\0", 47); + + $sent = \socket_send($sock, $msg, \strlen($msg), 0); + if ($sent === false) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to send NTP request: ' . \socket_strerror(\socket_last_error($sock))); + } + + $recv = false; + if (!\socket_recv($sock, $recv, 48, MSG_WAITALL)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to receive NTP response: ' . \socket_strerror(\socket_last_error($sock))); + } + + if ($recv === false || \strlen($recv) !== 48) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid NTP response: received ' . (\is_string($recv) ? \strlen($recv) : 'no') . ' bytes instead of 48'); + } + + $data = \unpack('N12', $recv); + $timestamp = \sprintf('%u', $data[9]); + + $timestamp -= 2208988800; + + $diff = ($timestamp - \time()); + + if ($diff > $gap || $diff < ($gap * -1)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Server time gaps detected'); + } + + $response->dynamic(new Document([ + 'remoteTime' => $timestamp, + 'localTime' => \time(), + 'diff' => $diff, + ]), Response::MODEL_HEALTH_TIME); + } finally { + \socket_close($sock); + } } }