| @@ -228,19 +228,10 @@ | ||
| 228 | 228 | $prefix = self::effective_salt( $opts ); |
| 229 | 229 | $timeout = self::int( $opts, 'connection_timeout', 1 ); |
| 230 | 230 | $persist = ! empty( $opts['persistent'] ); |
| 231 | 231 | |
| 232 | - // A socket is written the way Redis Object Cache expects one, | |
| 233 | - // scheme plus path, so the snippet works with that plugin too. | |
| 234 | - // xSpeed's drop-in reads the same pair. (#566) | |
| 235 | - $socket = Redis_Client::socket_path( $host ); | |
| 236 | - if ( '' !== $socket ) { | |
| 237 | - $lines[] = "define( 'WP_REDIS_SCHEME', 'unix' );"; | |
| 238 | - $lines[] = "define( 'WP_REDIS_PATH', '" . self::esc( $socket ) . "' );"; | |
| 239 | - } else { | |
| 240 | - $lines[] = "define( 'WP_REDIS_HOST', '" . self::esc( $host ) . "' );"; | |
| 241 | - $lines[] = "define( 'WP_REDIS_PORT', " . $port . ' );'; | |
| 242 | - } | |
| 232 | + $lines[] = "define( 'WP_REDIS_HOST', '" . self::esc( $host ) . "' );"; | |
| 233 | + $lines[] = "define( 'WP_REDIS_PORT', " . $port . ' );'; | |
| 243 | 234 | // Emit the ACL username only when set (Redis 6+). The drop-in |
| 244 | 235 | // reads it; an empty user keeps the legacy default-user behavior. |
| 245 | 236 | if ( '' !== $user ) { |
| 246 | 237 | $lines[] = "define( 'WP_REDIS_USER', '" . self::esc( $user ) . "' );"; |
| @@ -346,21 +337,13 @@ | ||
| 346 | 337 | $timeout = self::int( $opts, 'connection_timeout', 1 ); |
| 347 | 338 | $user = self::str( $opts, 'redis_user', '' ); |
| 348 | 339 | $pass = self::str( $opts, 'redis_password', '' ); |
| 349 | 340 | $db = self::int( $opts, 'redis_database', 0 ); |
| 350 | - // A socket path has no port. phpredis opens a socket only when the | |
| 351 | - // port is below 1, and the messages should name the path the user | |
| 352 | - // typed rather than "path:6379". (#566) | |
| 353 | - $socket = Redis_Client::socket_path( $host ); | |
| 354 | - $where = '' !== $socket ? $socket : "{$host}:{$port}"; | |
| 355 | 341 | |
| 356 | 342 | if ( class_exists( '\\Redis' ) ) { |
| 357 | - $redis = new \Redis(); | |
| 358 | - $connected = '' !== $socket | |
| 359 | - ? @$redis->connect( $socket, 0, $timeout ) | |
| 360 | - : @$redis->connect( $host, $port, $timeout ); | |
| 361 | - if ( ! $connected ) { | |
| 362 | - return self::test_result( false, $backend, "Could not connect to Redis at {$where}." ); | |
| 343 | + $redis = new \Redis(); | |
| 344 | + if ( ! @$redis->connect( $host, $port, $timeout ) ) { | |
| 345 | + return self::test_result( false, $backend, "Could not connect to Redis at {$host}:{$port}." ); | |
| 363 | 346 | } |
| 364 | 347 | // Redis 6+ ACL: when a username is set, authenticate as that user |
| 365 | 348 | // (phpredis ≥ 5.3 accepts ['user'=>..,'pass'=>..]); otherwise keep |
| 366 | 349 | // the legacy password-only form that authenticates as `default`. |
| @@ -373,9 +356,9 @@ | ||
| 373 | 356 | } |
| 374 | 357 | $pong = @$redis->ping(); |
| 375 | 358 | $ok = ( '+PONG' === $pong || true === $pong || 'PONG' === $pong ); |
| 376 | 359 | if ( ! $ok ) { |
| 377 | - return self::test_result( false, $backend, "Redis at {$where} did not respond to PING.", $start ); | |
| 360 | + return self::test_result( false, $backend, "Redis at {$host}:{$port} did not respond to PING.", $start ); | |
| 378 | 361 | } |
| 379 | 362 | // Write-verification: PING only proves auth, not that the user can |
| 380 | 363 | // STORE data. ACL-namespaced hosts (xCloud) restrict a user to a |
| 381 | 364 | // key pattern (~redis:<id>:*); a SET outside it is NOPERM-denied and |
| @@ -387,17 +370,17 @@ | ||
| 387 | 370 | $set = @$redis->set( $probe, '1', 5 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- NOPERM/denied is the negative answer we report, not a fatal. |
| 388 | 371 | $got = @$redis->get( $probe ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- same. |
| 389 | 372 | @$redis->del( $probe ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- best-effort cleanup. |
| 390 | 373 | if ( ! $set || '1' !== (string) $got ) { |
| 391 | - return self::test_result( false, $backend, self::write_denied_message( $opts, $where ), $start ); | |
| 374 | + return self::test_result( false, $backend, self::write_denied_message( $opts, $host, $port ), $start ); | |
| 392 | 375 | } |
| 393 | - return self::test_result( true, $backend, self::with_prefix_advisory( "Connected to Redis at {$where} (phpredis).", $opts ), $start ); | |
| 376 | + return self::test_result( true, $backend, self::with_prefix_advisory( "Connected to Redis at {$host}:{$port} (phpredis).", $opts ), $start ); | |
| 394 | 377 | } |
| 395 | 378 | |
| 396 | 379 | // Pure-PHP fallback — our own client, zero dependencies. |
| 397 | 380 | $rc = new Redis_Client( $host, $port, (float) $timeout, false ); |
| 398 | 381 | if ( ! $rc->connect() ) { |
| 399 | - return self::test_result( false, $backend, "Could not connect to Redis at {$where}." ); | |
| 382 | + return self::test_result( false, $backend, "Could not connect to Redis at {$host}:{$port}." ); | |
| 400 | 383 | } |
| 401 | 384 | // Authenticate when a user OR a password is set. Gating on password |
| 402 | 385 | // alone skipped auth for the "ACL user + empty password" case, which |
| 403 | 386 | // then failed later at PING with a misleading message. (FBS-83118 OC-1) |
| @@ -411,9 +394,9 @@ | ||
| 411 | 394 | $pong = $rc->ping(); |
| 412 | 395 | $ok = ( is_string( $pong ) && false !== stripos( $pong, 'PONG' ) ); |
| 413 | 396 | if ( ! $ok ) { |
| 414 | 397 | $rc->close(); |
| 415 | - return self::test_result( false, $backend, "Redis at {$where} did not respond to PING.", $start ); | |
| 398 | + return self::test_result( false, $backend, "Redis at {$host}:{$port} did not respond to PING.", $start ); | |
| 416 | 399 | } |
| 417 | 400 | // Write-verification round-trip — same rationale as the phpredis path |
| 418 | 401 | // above. (FBS-83118 OC-2) |
| 419 | 402 | $probe = self::probe_key( $opts ); |
| @@ -421,11 +404,11 @@ | ||
| 421 | 404 | $got = $rc->get( $probe ); |
| 422 | 405 | $rc->del( $probe ); |
| 423 | 406 | $rc->close(); |
| 424 | 407 | if ( ! $set || '1' !== (string) $got ) { |
| 425 | - return self::test_result( false, $backend, self::write_denied_message( $opts, $where ), $start ); | |
| 408 | + return self::test_result( false, $backend, self::write_denied_message( $opts, $host, $port ), $start ); | |
| 426 | 409 | } |
| 427 | - return self::test_result( true, $backend, self::with_prefix_advisory( "Connected to Redis at {$where} (built-in client).", $opts ), $start ); | |
| 410 | + return self::test_result( true, $backend, self::with_prefix_advisory( "Connected to Redis at {$host}:{$port} (built-in client).", $opts ), $start ); | |
| 428 | 411 | } catch ( \Throwable $e ) { |
| 429 | 412 | return self::test_result( false, $backend, 'Connection error: ' . $e->getMessage() ); |
| 430 | 413 | } |
| 431 | 414 | } |
| @@ -653,18 +636,19 @@ | ||
| 653 | 636 | * Message for a connect-OK-but-write-denied result. Points ACL/namespaced |
| 654 | 637 | * hosts at the fix (match the key prefix to the host's Redis Object Cache |
| 655 | 638 | * Key), which is exactly the xCloud failure mode. (FBS-83118 OC-2) |
| 656 | 639 | * |
| 657 | - * @param array $opts Settings array. | |
| 658 | - * @param string $where host:port, or the socket path. | |
| 640 | + * @param array $opts Settings array. | |
| 641 | + * @param string $host Redis host. | |
| 642 | + * @param int $port Redis port. | |
| 659 | 643 | * @return string |
| 660 | 644 | */ |
| 661 | - private static function write_denied_message( array $opts, string $where ): string { | |
| 645 | + private static function write_denied_message( array $opts, string $host, int $port ): string { | |
| 662 | 646 | $has_prefix = '' !== self::str( $opts, 'key_prefix', '' ); |
| 663 | 647 | $hint = $has_prefix |
| 664 | 648 | ? 'The Redis user may lack write permission for this key prefix (NOPERM).' |
| 665 | 649 | : 'On ACL/namespaced Redis (e.g. xCloud), set Cache key prefix to the host\'s "Redis Object Cache Key" so writes land in the permitted namespace.'; |
| 666 | - return "Connected to Redis at {$where}, but the cache could not store data. {$hint}"; | |
| 650 | + return "Connected to Redis at {$host}:{$port}, but the cache could not store data. {$hint}"; | |
| 667 | 651 | } |
| 668 | 652 | |
| 669 | 653 | /** |
| 670 | 654 | * Full plug-and-play enable: test → write wp-config constants → install |