Skip to content

Commit 0f9ca8e

Browse files
author
zhenghaosheng1
committed
Merge remote-tracking branch 'remotes/auth/develop' into develop
# Conflicts: # cluster_library.c # common.h # library.c # library.h # redis.c # redis_array_impl.c # redis_cluster.c # redis_commands.c # redis_session.c
2 parents 1bb7fe4 + b55b624 commit 0f9ca8e

File tree

9 files changed

+107
-25
lines changed

9 files changed

+107
-25
lines changed

cluster.markdown

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ $obj_cluster = new RedisCluster(NULL, Array("host:7000", "host:7001"), 1.5, 1.5)
1919
// persistent connections to each node.
2020
$obj_cluster = new RedisCluster(NULL, Array("host:7000", "host:7001"), 1.5, 1.5, true);
2121

22+
// Connect with cluster using password.
23+
$obj_cluster = new RedisCluster(NULL, Array("host:7000", "host:7001"), 1.5, 1.5, true, "password");
24+
2225
</pre>
2326

2427
#### Loading a cluster configuration by name
@@ -29,6 +32,7 @@ In order to load a named array, one must first define the seed nodes in redis.in
2932
redis.clusters.seeds = "mycluster[]=localhost:7000&test[]=localhost:7001"
3033
redis.clusters.timeout = "mycluster=5"
3134
redis.clusters.read_timeout = "mycluster=10"
35+
redis.clusters.auth = "mycluster=password"
3236
</pre>
3337

3438
Then, this cluster can be loaded by doing the following
@@ -161,7 +165,7 @@ To do this, you must configure your `session.save_handler` and `session.save_pat
161165

162166
~~~
163167
session.save_handler = rediscluster
164-
session.save_path = "seed[]=host1:port1&seed[]=host2:port2&seed[]=hostN:portN&timeout=2&read_timeout=2&failover=error&persistent=1"
168+
session.save_path = "seed[]=host1:port1&seed[]=host2:port2&seed[]=hostN:portN&timeout=2&read_timeout=2&failover=error&persistent=1&auth=password"
165169
~~~
166170

167171
### session.session_handler
@@ -175,5 +179,6 @@ The save path for cluster based session storage takes the form of a PHP GET requ
175179
* _persistent_: Tells phpredis whether persistent connections should be used.
176180
* _distribute_: phpredis will randomly distribute session reads between masters and any attached slaves (load balancing).
177181
* _failover (string)_: How phpredis should distribute session reads between master and slave nodes.
182+
* _auth (string, empty by default)_: The password used to authenticate with the server prior to sending commands.
178183
* * _none_ : phpredis will only communicate with master nodes
179184
* * _error_: phpredis will communicate with master nodes unless one failes, in which case an attempt will be made to read session information from a slave.

cluster_library.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ clusterReply* cluster_get_slots(RedisSock *redis_sock TSRMLS_DC)
609609
REDIS_REPLY_TYPE type;
610610
long len;
611611

612+
if (redis_sock->auth && resend_auth(redis_sock TSRMLS_CC) != 0) {
613+
return NULL;
614+
}
615+
612616
// Send the command to the socket and consume reply type
613617
if (redis_sock_write(redis_sock, RESP_CLUSTER_SLOTS_CMD,
614618
sizeof(RESP_CLUSTER_SLOTS_CMD)-1 TSRMLS_CC) < 0 ||
@@ -642,8 +646,8 @@ cluster_node_create(redisCluster *c, char *host, size_t host_len,
642646
node->slaves = NULL;
643647

644648
// Attach socket
645-
node->sock = redis_sock_create(host, host_len, port, c->timeout,
646-
c->read_timeout, c->persistent, NULL, 0, 1);
649+
node->sock = redis_sock_create(host, host_len, port, c->auth, c->auth_len,
650+
c->timeout, c->read_timeout,c->persistent, NULL, 0, 1);
647651

648652
return node;
649653
}
@@ -800,7 +804,7 @@ static void ht_free_node(zval *data)
800804

801805
/* Construct a redisCluster object */
802806
PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
803-
int failover, int persistent)
807+
int failover, int persistent, char *auth, int auth_len)
804808
{
805809
redisCluster *c;
806810

@@ -815,6 +819,8 @@ PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
815819
c->read_timeout = read_timeout;
816820
c->failover = failover;
817821
c->persistent = persistent;
822+
c->auth = auth;
823+
c->auth_len = auth_len;
818824
c->err = NULL;
819825

820826
/* Set up our waitms based on timeout */
@@ -913,8 +919,8 @@ cluster_init_seeds(redisCluster *cluster, HashTable *ht_seeds) {
913919

914920
// Allocate a structure for this seed
915921
redis_sock = redis_sock_create(str, psep-str,
916-
(unsigned short)atoi(psep+1), cluster->timeout,
917-
cluster->read_timeout, cluster->persistent, NULL, 0, 0);
922+
(unsigned short)atoi(psep+1), cluster->auth, cluster->auth_len,
923+
cluster->timeout, cluster->read_timeout, cluster->persistent, NULL, 0, 0);
918924

919925
// Index this seed by host/port
920926
key_len = snprintf(key, sizeof(key), "%s:%u", ZSTR_VAL(redis_sock->host),

cluster_library.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,26 @@
5252
memcmp(ZSTR_VAL(SLOT_SOCK(c,c->redir_slot)->host),c->redir_host,c->redir_host_len))
5353

5454
/* Lazy connect logic */
55+
#if 0
5556
#define CLUSTER_LAZY_CONNECT(s) \
5657
if(s->lazy_connect) { \
5758
s->lazy_connect = 0; \
5859
redis_sock_server_open(s TSRMLS_CC); \
5960
}
61+
#endif
62+
#define CLUSTER_LAZY_CONNECT(s) \
63+
int needs_auth = 0; \
64+
if(s->lazy_connect) { \
65+
s->lazy_connect = 0; \
66+
if(s->auth && s->status != REDIS_SOCK_STATUS_CONNECTED) {\
67+
needs_auth = 1;\
68+
}\
69+
redis_sock_server_open(s TSRMLS_CC); \
70+
if(needs_auth) {\
71+
resend_auth(s TSRMLS_CC);\
72+
}\
73+
}
74+
6075

6176
/* Clear out our "last error" */
6277
#define CLUSTER_CLEAR_ERROR(c) do { \
@@ -177,6 +192,10 @@ typedef struct redisCluster {
177192
zend_object std;
178193
#endif
179194

195+
/*RedisCluster auth*/
196+
char *auth;
197+
int auth_len;
198+
180199
/* Timeout and read timeout (for normal operations) */
181200
double timeout;
182201
double read_timeout;
@@ -367,7 +386,7 @@ PHP_REDIS_API int cluster_send_slot(redisCluster *c, short slot, char *cmd,
367386
int cmd_len, REDIS_REPLY_TYPE rtype TSRMLS_DC);
368387

369388
PHP_REDIS_API redisCluster *cluster_create(double timeout, double read_timeout,
370-
int failover, int persistent);
389+
int failover, int persistent, char *auth, int auth_len);
371390
PHP_REDIS_API void cluster_free(redisCluster *c, int free_ctx TSRMLS_DC);
372391
PHP_REDIS_API int cluster_init_seeds(redisCluster *c, HashTable *ht_seeds);
373392
PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC);

library.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static int reselect_db(RedisSock *redis_sock TSRMLS_DC) {
8686
}
8787

8888
/* Helper to resend AUTH <password> in the case of a reconnect */
89-
static int resend_auth(RedisSock *redis_sock TSRMLS_DC) {
89+
int resend_auth(RedisSock *redis_sock TSRMLS_DC) {
9090
char *cmd, *response;
9191
int cmd_len, response_len;
9292

@@ -1364,8 +1364,8 @@ PHP_REDIS_API void redis_debug_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock
13641364
* redis_sock_create
13651365
*/
13661366
PHP_REDIS_API RedisSock*
1367-
redis_sock_create(char *host, int host_len, unsigned short port,
1368-
double timeout, double read_timeout,
1367+
redis_sock_create(char *host, int host_len, unsigned short port, char *auth,
1368+
int auth_len, double timeout, double read_timeout,
13691369
int persistent, char *persistent_id,
13701370
long retry_interval, zend_bool lazy_connect)
13711371
{
@@ -1390,6 +1390,10 @@ redis_sock_create(char *host, int host_len, unsigned short port,
13901390
redis_sock->timeout = timeout;
13911391
redis_sock->read_timeout = read_timeout;
13921392

1393+
if (auth && auth_len){
1394+
redis_sock->auth = zend_string_init(auth, auth_len, 0);
1395+
}
1396+
13931397
redis_sock->serializer = REDIS_SERIALIZER_NONE;
13941398
redis_sock->compression = REDIS_COMPRESSION_NONE;
13951399
redis_sock->mode = ATOMIC;

library.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ PHP_REDIS_API void redis_info_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *
3838
PHP_REDIS_API void redis_parse_info_response(char *response, zval *z_ret);
3939
PHP_REDIS_API void redis_parse_client_list_response(char *response, zval *z_ret);
4040
PHP_REDIS_API void redis_type_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
41-
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, unsigned short port, double timeout, double read_timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
41+
PHP_REDIS_API RedisSock* redis_sock_create(char *host, int host_len, unsigned short port,
42+
char *auth, int auth_len, double timeout, double read_timeout, int persistent, char *persistent_id, long retry_interval, zend_bool lazy_connect);
4243
PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC);
4344
PHP_REDIS_API int redis_sock_server_open(RedisSock *redis_sock TSRMLS_DC);
4445
PHP_REDIS_API int redis_sock_disconnect(RedisSock *redis_sock TSRMLS_DC);

redis.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ PHP_INI_BEGIN()
7272
PHP_INI_ENTRY("redis.clusters.persistent", "", PHP_INI_ALL, NULL)
7373
PHP_INI_ENTRY("redis.clusters.read_timeout", "", PHP_INI_ALL, NULL)
7474
PHP_INI_ENTRY("redis.clusters.seeds", "", PHP_INI_ALL, NULL)
75+
PHP_INI_ENTRY("redis.clusters.auth", "", PHP_INI_ALL, NULL)
7576
PHP_INI_ENTRY("redis.clusters.timeout", "", PHP_INI_ALL, NULL)
7677

7778
/* redis session */
@@ -950,7 +951,7 @@ redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
950951
redis_free_socket(redis->sock);
951952
}
952953

953-
redis->sock = redis_sock_create(host, host_len, port, timeout, read_timeout, persistent,
954+
redis->sock = redis_sock_create(host, host_len, port, NULL, 0, timeout, read_timeout, persistent,
954955
persistent_id, retry_interval, 0);
955956

956957
if (redis_sock_server_open(redis->sock TSRMLS_CC) < 0) {

redis_array_impl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval, zend_bool b
7272
redis = PHPREDIS_GET_OBJECT(redis_object, &ra->redis[i]);
7373

7474
/* create socket */
75-
redis->sock = redis_sock_create(host, host_len, port, ra->connect_timeout, ra->read_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);
75+
redis->sock = redis_sock_create(host, host_len, port, NULL, 0, ra->connect_timeout, ra->read_timeout, ra->pconnect, NULL, retry_interval, b_lazy_connect);
7676

7777
if (!b_lazy_connect)
7878
{

redis_cluster.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,8 @@ free_cluster_context(zend_object *object)
384384
#endif
385385

386386
/* Attempt to connect to a Redis cluster provided seeds and timeout options */
387-
void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
388-
double read_timeout, int persistent TSRMLS_DC)
387+
void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, char *auth, int auth_len,
388+
double timeout, double read_timeout, int persistent TSRMLS_DC)
389389
{
390390
// Validate timeout
391391
if (timeout < 0L || timeout > INT_MAX) {
@@ -404,6 +404,12 @@ void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
404404
zend_throw_exception(redis_cluster_exception_ce,
405405
"Must pass seeds", 0 TSRMLS_CC);
406406
}
407+
// Redis Cluster auth
408+
if (auth && auth_len > 0){
409+
c->auth = estrndup(auth, auth_len);
410+
c->auth_len = auth_len;
411+
}
412+
407413
/* Set our timeout and read_timeout which we'll pass through to the
408414
* socket type operations */
409415
c->timeout = timeout;
@@ -421,15 +427,19 @@ void redis_cluster_init(redisCluster *c, HashTable *ht_seeds, double timeout,
421427

422428
// Create and map our key space
423429
cluster_map_keyspace(c TSRMLS_CC);
430+
431+
efree(c->auth);
424432
}
425433

426434
/* Attempt to load a named cluster configured in php.ini */
427435
void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
428-
zval z_seeds, z_timeout, z_read_timeout, z_persistent, *z_value;
436+
zval z_seeds, z_auth, z_timeout, z_read_timeout, z_persistent, *z_value;
429437
char *iptr;
430438
double timeout = 0, read_timeout = 0;
431439
int persistent = 0;
432440
HashTable *ht_seeds = NULL;
441+
char *auth = NULL;
442+
int auth_len = 0;
433443

434444
/* Seeds */
435445
array_init(&z_seeds);
@@ -444,6 +454,25 @@ void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
444454
return;
445455
}
446456

457+
458+
/* auth */
459+
array_init(&z_auth);
460+
if ((iptr = INI_STR("redis.clusters.auth")) != NULL) {
461+
sapi_module.treat_data(PARSE_STRING, estrdup(iptr), &z_auth TSRMLS_CC);
462+
}
463+
if ((z_value = zend_hash_str_find(Z_ARRVAL(z_auth), name, name_len)) != NULL) {
464+
if (Z_TYPE_P(z_value) == IS_STRING) {
465+
auth = Z_STRVAL_P(z_value);
466+
auth_len = strlen(auth);
467+
} else {
468+
zval_dtor(&z_seeds);
469+
zval_dtor(&z_auth);
470+
zend_throw_exception(redis_cluster_exception_ce, "Couldn't find legal auth for cluster", 0 TSRMLS_CC);
471+
return;
472+
}
473+
}
474+
475+
447476
/* Connection timeout */
448477
array_init(&z_timeout);
449478
if ((iptr = INI_STR("redis.clusters.timeout")) != NULL) {
@@ -488,13 +517,14 @@ void redis_cluster_load(redisCluster *c, char *name, int name_len TSRMLS_DC) {
488517
}
489518

490519
/* Attempt to create/connect to the cluster */
491-
redis_cluster_init(c, ht_seeds, timeout, read_timeout, persistent TSRMLS_CC);
520+
redis_cluster_init(c, ht_seeds, auth, auth_len, timeout, read_timeout, persistent TSRMLS_CC);
492521

493522
/* Clean up our arrays */
494523
zval_dtor(&z_seeds);
495524
zval_dtor(&z_timeout);
496525
zval_dtor(&z_read_timeout);
497526
zval_dtor(&z_persistent);
527+
zval_dtor(&z_auth);
498528
}
499529

500530
/*
@@ -506,15 +536,18 @@ PHP_METHOD(RedisCluster, __construct) {
506536
zval *object, *z_seeds = NULL;
507537
char *name;
508538
strlen_t name_len;
539+
char *auth = NULL;
540+
int auth_len = 0;
509541
double timeout = 0.0, read_timeout = 0.0;
510542
zend_bool persistent = 0;
511543
redisCluster *context = GET_CONTEXT();
512544

513545
// Parse arguments
514546
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
515-
"Os!|addb", &object, redis_cluster_ce, &name,
547+
"Os!|addbs", &object, redis_cluster_ce, &name,
516548
&name_len, &z_seeds, &timeout,
517-
&read_timeout, &persistent) == FAILURE)
549+
&read_timeout, &persistent,
550+
&auth, &auth_len)==FAILURE)
518551
{
519552
RETURN_FALSE;
520553
}
@@ -529,7 +562,7 @@ PHP_METHOD(RedisCluster, __construct) {
529562
/* If we've been passed only one argument, the user is attempting to connect
530563
* to a named cluster, stored in php.ini, otherwise we'll need manual seeds */
531564
if (ZEND_NUM_ARGS() > 1) {
532-
redis_cluster_init(context, Z_ARRVAL_P(z_seeds), timeout, read_timeout,
565+
redis_cluster_init(context, Z_ARRVAL_P(z_seeds), auth, auth_len, timeout, read_timeout,
533566
persistent TSRMLS_CC);
534567
} else {
535568
redis_cluster_load(context, name, name_len TSRMLS_CC);

redis_session.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -509,15 +509,15 @@ PS_OPEN_FUNC(redis)
509509
RedisSock *redis_sock;
510510
if (url->host) {
511511
#if (PHP_VERSION_ID < 70300)
512-
redis_sock = redis_sock_create(url->host, strlen(url->host), url->port, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
512+
redis_sock = redis_sock_create(url->host, strlen(url->host), url->port, NULL, 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
513513
#else
514-
redis_sock = redis_sock_create(ZSTR_VAL(url->host), ZSTR_LEN(url->host), url->port, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
514+
redis_sock = redis_sock_create(ZSTR_VAL(url->host), ZSTR_LEN(url->host), url->port, NULL, 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
515515
#endif
516516
} else { /* unix */
517517
#if (PHP_VERSION_ID < 70300)
518-
redis_sock = redis_sock_create(url->path, strlen(url->path), 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
518+
redis_sock = redis_sock_create(url->path, strlen(url->path), 0, NULL, 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
519519
#else
520-
redis_sock = redis_sock_create(ZSTR_VAL(url->path), ZSTR_LEN(url->path), 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
520+
redis_sock = redis_sock_create(ZSTR_VAL(url->path), ZSTR_LEN(url->path), 0, NULL, 0, timeout, read_timeout, persistent, persistent_id, retry_interval, 0);
521521
#endif
522522
}
523523
redis_pool_add(pool, redis_sock, weight, database, prefix, auth TSRMLS_CC);
@@ -982,6 +982,8 @@ PS_OPEN_FUNC(rediscluster) {
982982
int persistent = 0;
983983
int retval, prefix_len, failover = REDIS_FAILOVER_NONE;
984984
char *prefix;
985+
char *auth;
986+
int auth_len;
985987

986988
/* Parse configuration for session handler */
987989
array_init(&z_conf);
@@ -1037,7 +1039,18 @@ PS_OPEN_FUNC(rediscluster) {
10371039
}
10381040
}
10391041

1040-
c = cluster_create(timeout, read_timeout, failover, persistent);
1042+
/* Look for a specific prefix */
1043+
if ((z_val = zend_hash_str_find(ht_conf, "auth", sizeof("auth") - 1)) != NULL &&
1044+
Z_TYPE_P(z_val) == IS_STRING && Z_STRLEN_P(z_val) > 0
1045+
) {
1046+
auth = Z_STRVAL_P(z_val);
1047+
auth_len = Z_STRLEN_P(z_val);
1048+
} else {
1049+
auth = NULL;
1050+
auth_len = 0;
1051+
}
1052+
1053+
c = cluster_create(timeout, read_timeout, failover, persistent, auth, auth_len);
10411054
if (!cluster_init_seeds(c, ht_seeds) && !cluster_map_keyspace(c TSRMLS_CC)) {
10421055
/* Set up our prefix */
10431056
c->flags->prefix = zend_string_init(prefix, prefix_len, 0);

0 commit comments

Comments
 (0)