Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ed1da64

Browse files
Merge branch 'develop-ipv6' into develop
2 parents 07c9f99 + 3012052 commit ed1da64

File tree

8 files changed

+84
-47
lines changed

8 files changed

+84
-47
lines changed

cluster_library.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,9 @@ cluster_init_seeds(redisCluster *cluster, HashTable *ht_seeds) {
918918
// Grab a copy of the string
919919
str = Z_STRVAL_P(z_seed);
920920

921-
// Must be in host:port form
922-
if(!(psep = strchr(str, ':')))
921+
/* Make sure we have a colon for host:port. Search right to left in the
922+
* case of IPv6 */
923+
if ((psep = strrchr(str, ':')) == NULL)
923924
continue;
924925

925926
// Allocate a structure for this seed
@@ -996,12 +997,12 @@ static int cluster_set_redirection(redisCluster* c, char *msg, int moved)
996997
/* Move past "MOVED" or "ASK */
997998
msg += moved ? MOVED_LEN : ASK_LEN;
998999

999-
// We need a slot seperator
1000-
if(!(host = strchr(msg, ' '))) return -1;
1000+
/* Make sure we can find host */
1001+
if ((host = strchr(msg, ' ')) == NULL) return -1;
10011002
*host++ = '\0';
10021003

1003-
// We need a : that seperates host from port
1004-
if(!(port = strchr(host,':'))) return -1;
1004+
/* Find port, searching right to left in case of IPv6 */
1005+
if ((port = strrchr(host, ':')) == NULL) return -1;
10051006
*port++ = '\0';
10061007

10071008
// Success, apply it

library.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,7 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
16101610
{
16111611
struct timeval tv, read_tv, *tv_ptr = NULL;
16121612
char *host = NULL, *persistent_id = NULL, *errstr = NULL;
1613+
const char *fmtstr = "%s:%d";
16131614
int host_len, err = 0;
16141615
php_netstream_data_t *sock;
16151616
int tcp_flag = 1;
@@ -1632,8 +1633,15 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
16321633
} else {
16331634
if(redis_sock->port == 0)
16341635
redis_sock->port = 6379;
1635-
host_len = spprintf(&host, 0, "%s:%d", redis_sock->host,
1636-
redis_sock->port);
1636+
1637+
#ifdef HAVE_IPV6
1638+
/* If we've got IPv6 and find a colon in our address, convert to proper
1639+
* IPv6 [host]:port format */
1640+
if (strchr(redis_sock->host, ':') != NULL) {
1641+
fmtstr = "[%s]:%d";
1642+
}
1643+
#endif
1644+
host_len = spprintf(&host, 0, fmtstr, redis_sock->host, redis_sock->port);
16371645
}
16381646

16391647
if (redis_sock->persistent) {

redis_array_impl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b
5757
host_len = Z_STRLEN_PP(zpData);
5858
port = 6379;
5959

60-
if((p = strchr(host, ':'))) { /* found port */
60+
if((p = strrchr(host, ':'))) { /* found port */
6161
host_len = p - host;
6262
port = (short)atoi(p+1);
6363
} else if(strchr(host,'/') != NULL) { /* unix socket */

tests/RedisArrayTest.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@ function custom_hash($str) {
1212
return $str;
1313
}
1414

15+
function parseHostPort($str, &$host, &$port) {
16+
$pos = strrpos($str, ':');
17+
$host = substr($str, 0, $pos);
18+
$port = substr($str, $pos+1);
19+
}
20+
1521
class Redis_Array_Test extends TestSuite
1622
{
1723
private $strings;
1824
public $ra = NULL;
1925
private $data = NULL;
2026

2127
public function setUp() {
22-
2328
// initialize strings.
2429
$n = REDIS_ARRAY_DATA_SIZE;
2530
$this->strings = array();
@@ -42,7 +47,13 @@ public function testMSet() {
4247

4348
// check each key individually using a new connection
4449
foreach($this->strings as $k => $v) {
45-
list($host, $port) = split(':', $this->ra->_target($k));
50+
parseHostPort($this->ra->_target($k), $host, $port);
51+
52+
$target = $this->ra->_target($k);
53+
$pos = strrpos($target, ':');
54+
55+
$host = substr($target, 0, $pos);
56+
$port = substr($target, $pos+1);
4657

4758
$r = new Redis;
4859
$r->pconnect($host, (int)$port);
@@ -180,7 +191,7 @@ public function testFlush() {
180191
// flush all servers first.
181192
global $serverList;
182193
foreach($serverList as $s) {
183-
list($host, $port) = explode(':', $s);
194+
parseHostPort($s, $host, $port);
184195

185196
$r = new Redis();
186197
$r->pconnect($host, (int)$port, 0);
@@ -354,11 +365,8 @@ public function testReadAndMigrateAll() {
354365
// Read and migrate keys on fallback, causing the whole ring to be rehashed.
355366
public function testAllKeysHaveBeenMigrated() {
356367
foreach($this->strings as $k => $v) {
357-
// get the target for each key
358-
$target = $this->ra->_target($k);
368+
parseHostPort($this->ra->_target($k), $host, $port);
359369

360-
// connect to the target host
361-
list($host,$port) = split(':', $target);
362370
$r = new Redis;
363371
$r->pconnect($host, $port);
364372

@@ -531,12 +539,13 @@ public function testDistribution() {
531539
}
532540
}
533541

534-
function run_tests($className, $str_filter) {
542+
function run_tests($className, $str_filter, $str_host) {
535543
// reset rings
536544
global $newRing, $oldRing, $serverList;
537-
$newRing = array('localhost:6379', 'localhost:6380', 'localhost:6381');
538-
$oldRing = array();
539-
$serverList = array('localhost:6379', 'localhost:6380', 'localhost:6381', 'localhost:6382');
545+
546+
$newRing = Array("$str_host:6379", "$str_host:6380", "$str_host:6381");
547+
$oldRing = Array();
548+
$serverList = Array("$str_host:6379", "$str_host:6380", "$str_host:6381", "$str_host:6382");
540549

541550
// run
542551
TestSuite::run($className, $str_filter);

tests/RedisTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
class Redis_Test extends TestSuite
66
{
7-
const HOST = '127.0.0.1';
87
const PORT = 6379;
98
const AUTH = NULL; //replace with a string to use Redis authentication
109

@@ -21,7 +20,8 @@ public function setUp() {
2120

2221
protected function newInstance() {
2322
$r = new Redis();
24-
$r->connect(self::HOST, self::PORT);
23+
24+
$r->connect($this->getHost(), self::PORT);
2525

2626
if(self::AUTH) {
2727
$this->assertTrue($r->auth(self::AUTH));
@@ -4485,7 +4485,7 @@ public function testReadTimeoutOption() {
44854485

44864486
public function testIntrospection() {
44874487
// Simple introspection tests
4488-
$this->assertTrue($this->redis->getHost() === self::HOST);
4488+
$this->assertTrue($this->redis->getHost() === $this->getHost());
44894489
$this->assertTrue($this->redis->getPort() === self::PORT);
44904490
$this->assertTrue($this->redis->getAuth() === self::AUTH);
44914491
}

tests/TestRedis.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
ini_set( 'display_errors','1');
1111

1212
/* Grab options */
13-
$arr_args = getopt('', Array('class:', 'test:', 'nocolors'));
13+
$arr_args = getopt('', Array('host:', 'class:', 'test:', 'nocolors'));
1414

1515
/* Grab the test the user is trying to run */
1616
$arr_valid_classes = Array('redis', 'redisarray', 'rediscluster');
@@ -20,6 +20,9 @@
2020
/* Get our test filter if provided one */
2121
$str_filter = isset($arr_args['test']) ? $arr_args['test'] : NULL;
2222

23+
/* Grab override test host if it was passed */
24+
$str_host = isset($arr_args['host']) ? $arr_args['host'] : '127.0.0.1';
25+
2326
/* Validate the class is known */
2427
if (!in_array($str_class, $arr_valid_classes)) {
2528
echo "Error: Valid test classes are Redis, RedisArray, and RedisCluster!\n";
@@ -36,21 +39,21 @@
3639
echo "Testing class ";
3740
if ($str_class == 'redis') {
3841
echo TestSuite::make_bold("Redis") . "\n";
39-
exit(TestSuite::run("Redis_Test", $str_filter));
42+
exit(TestSuite::run("Redis_Test", $str_filter, $str_host));
4043
} else if ($str_class == 'redisarray') {
4144
echo TestSuite::make_bold("RedisArray") . "\n";
4245
global $useIndex;
4346
foreach(array(true, false) as $useIndex) {
4447
echo "\n".($useIndex?"WITH":"WITHOUT"). " per-node index:\n";
4548

46-
run_tests('Redis_Array_Test', $str_filter);
47-
run_tests('Redis_Rehashing_Test', $str_filter);
48-
run_tests('Redis_Auto_Rehashing_Test', $str_filter);
49-
run_tests('Redis_Multi_Exec_Test', $str_filter);
50-
run_tests('Redis_Distributor_Test', $str_filter);
49+
run_tests('Redis_Array_Test', $str_filter, $str_host);
50+
run_tests('Redis_Rehashing_Test', $str_filter, $str_host);
51+
run_tests('Redis_Auto_Rehashing_Test', $str_filter, $str_host);
52+
run_tests('Redis_Multi_Exec_Test', $str_filter, $str_host);
53+
run_tests('Redis_Distributor_Test', $str_filter, $str_host);
5154
}
5255
} else {
5356
echo TestSuite::make_bold("RedisCluster") . "\n";
54-
exit(TestSuite::run("Redis_Cluster_Test", $str_filter));
57+
exit(TestSuite::run("Redis_Cluster_Test", $str_filter, $str_host));
5558
}
5659
?>

tests/TestSuite.php

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
// phpunit is such a pain to install, we're going with pure-PHP here.
44
class TestSuite {
5+
/* Host the tests will use */
6+
private $str_host;
7+
58
private static $_boo_colorize = false;
69

710
private static $BOLD_ON = "\033[1m";
@@ -18,8 +21,14 @@ class TestSuite {
1821
public static $errors = array();
1922
public static $warnings = array();
2023

24+
public function __construct($str_host) {
25+
$this->str_host = $str_host;
26+
}
27+
28+
public function getHost() { return $this->str_host; }
29+
2130
public static function make_bold($str_msg) {
22-
return self::$_boo_colorize
31+
return self::$_boo_colorize
2332
? self::$BOLD_ON . $str_msg . self::$BOLD_OFF
2433
: $str_msg;
2534
}
@@ -56,7 +65,7 @@ protected function assertTrue($bool) {
5665
}
5766

5867
protected function assertLess($a, $b) {
59-
if($a < $b)
68+
if($a < $b)
6069
return;
6170

6271
$bt = debug_backtrace(false);
@@ -85,12 +94,12 @@ protected function markTestSkipped($msg='') {
8594

8695
private static function getMaxTestLen($arr_methods, $str_limit) {
8796
$i_result = 0;
88-
97+
8998
$str_limit = strtolower($str_limit);
9099
foreach ($arr_methods as $obj_method) {
91100
$str_name = strtolower($obj_method->name);
92101

93-
if (substr($str_name, 0, 4) != 'test')
102+
if (substr($str_name, 0, 4) != 'test')
94103
continue;
95104
if ($str_limit && !strstr($str_name, $str_limit))
96105
continue;
@@ -101,14 +110,14 @@ private static function getMaxTestLen($arr_methods, $str_limit) {
101110
}
102111
return $i_result;
103112
}
104-
113+
105114
/* Flag colorization */
106115
public static function flagColorization($boo_override) {
107116
self::$_boo_colorize = $boo_override && function_exists('posix_isatty') &&
108117
posix_isatty(STDOUT);
109118
}
110119

111-
public static function run($className, $str_limit = NULL) {
120+
public static function run($className, $str_limit = NULL, $str_host = NULL) {
112121
/* Lowercase our limit arg if we're passed one */
113122
$str_limit = $str_limit ? strtolower($str_limit) : $str_limit;
114123

@@ -121,7 +130,7 @@ public static function run($className, $str_limit = NULL) {
121130
$name = $m->name;
122131
if(substr($name, 0, 4) !== 'test')
123132
continue;
124-
133+
125134
/* If we're trying to limit to a specific test and can't match the
126135
* substring, skip */
127136
if ($str_limit && strstr(strtolower($name), $str_limit)===FALSE) {
@@ -132,7 +141,8 @@ public static function run($className, $str_limit = NULL) {
132141
echo self::make_bold($str_out_name);
133142

134143
$count = count($className::$errors);
135-
$rt = new $className();
144+
$rt = new $className($str_host);
145+
136146
try {
137147
$rt->setUp();
138148
$rt->$name();

tests/make-cluster.sh

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
# simplifying the process of running unit tests.
66
#
77
# Usage:
8-
# ./make-cluster.sh start
9-
# ./make-cluster.sh stop
8+
# ./make-cluster.sh start [host]
9+
# ./make-cluster.sh stop [host]
1010
#
1111

12-
BASEDIR=`dirname $@`
12+
BASEDIR=`pwd`
1313
NODEDIR=$BASEDIR/nodes
1414
MAPFILE=$NODEDIR/nodemap
1515

16-
# Nodes, replicas, ports, etc. Change if you want different values
16+
# Host, nodes, replicas, ports, etc. Change if you want different values
17+
HOST="127.0.0.1"
1718
NODES=12
1819
REPLICAS=3
1920
START_PORT=7000
@@ -38,7 +39,7 @@ spawnNode() {
3839
# Attempt to spawn the node
3940
verboseRun redis-server --cluster-enabled yes --dir $NODEDIR --port $PORT \
4041
--cluster-config-file node-$PORT.conf --daemonize yes --save \'\' \
41-
--bind '127.0.0.1' --dbfilename node-$PORT.rdb
42+
--bind $HOST --dbfilename node-$PORT.rdb
4243

4344
# Abort if we can't spin this instance
4445
if [ $? -ne 0 ]; then
@@ -54,7 +55,7 @@ spawnNodes() {
5455
spawnNode $PORT
5556

5657
# Add this host:port to our nodemap so the tests can get seeds
57-
echo "127.0.0.1:$PORT" >> $MAPFILE
58+
echo "$HOST:$PORT" >> $MAPFILE
5859
done
5960
}
6061

@@ -85,7 +86,7 @@ cleanConfigInfo() {
8586
initCluster() {
8687
TRIBARGS=""
8788
for PORT in `seq $START_PORT $END_PORT`; do
88-
TRIBARGS="$TRIBARGS 127.0.0.1:$PORT"
89+
TRIBARGS="$TRIBARGS $HOST:$PORT"
8990
done
9091

9192
verboseRun redis-trib.rb create --replicas $REPLICAS $TRIBARGS
@@ -122,6 +123,11 @@ stopCluster() {
122123
checkExe redis-server
123124
checkExe redis-trib.rb
124125

126+
# Override the host if we've got $2
127+
if [[ ! -z "$2" ]]; then
128+
HOST=$2
129+
fi
130+
125131
# Main entry point to start or stop/kill a cluster
126132
case "$1" in
127133
start)
@@ -131,6 +137,6 @@ case "$1" in
131137
stopCluster
132138
;;
133139
*)
134-
echo "Usage $0 [start|stop]"
140+
echo "Usage $0 <start|stop> [host]"
135141
;;
136142
esac

0 commit comments

Comments
 (0)