@@ -685,19 +685,6 @@ redis_sock_read(RedisSock *redis_sock, int *buf_len)
685
685
return NULL ;
686
686
}
687
687
688
- static int redis_sock_read_cmp (RedisSock * redis_sock , const char * cmp , int cmplen ) {
689
- char * resp ;
690
- int len , rv = FAILURE ;
691
-
692
- if ((resp = redis_sock_read (redis_sock , & len )) == NULL )
693
- return FAILURE ;
694
-
695
- rv = len == cmplen && !memcmp (resp , cmp , cmplen ) ? SUCCESS : FAILURE ;
696
-
697
- efree (resp );
698
- return rv ;
699
- }
700
-
701
688
/* A simple union to store the various arg types we might handle in our
702
689
* redis_spprintf command formatting function */
703
690
union resparg {
@@ -2129,16 +2116,21 @@ static int redis_stream_liveness_check(php_stream *stream) {
2129
2116
static int
2130
2117
redis_sock_check_liveness (RedisSock * redis_sock )
2131
2118
{
2132
- char id [64 ], ok ;
2119
+ char id [64 ], inbuf [ 4096 ] ;
2133
2120
int idlen , auth ;
2134
2121
smart_string cmd = {0 };
2122
+ size_t len ;
2135
2123
2136
2124
/* Short circuit if we detect the stream has gone bad or if the user has
2137
2125
* configured persistent connection "YOLO mode". */
2138
- if (redis_stream_liveness_check (redis_sock -> stream ) != SUCCESS )
2139
- return FAILURE ;
2140
- else if (!INI_INT ("redis.pconnect.echo_check_liveness" ))
2126
+ if (redis_stream_liveness_check (redis_sock -> stream ) != SUCCESS ) {
2127
+ goto failure ;
2128
+ }
2129
+
2130
+ redis_sock -> status = REDIS_SOCK_STATUS_CONNECTED ;
2131
+ if (!INI_INT ("redis.pconnect.echo_check_liveness" )) {
2141
2132
return SUCCESS ;
2133
+ }
2142
2134
2143
2135
/* AUTH (if we need it) */
2144
2136
auth = redis_sock_append_auth (redis_sock , & cmd );
@@ -2149,12 +2141,55 @@ redis_sock_check_liveness(RedisSock *redis_sock)
2149
2141
redis_cmd_append_sstr (& cmd , id , idlen );
2150
2142
2151
2143
/* Send command(s) and make sure we can consume reply(ies) */
2152
- ok = (redis_sock_write (redis_sock , cmd .c , cmd .len ) >= 0 ) &&
2153
- (! auth || redis_sock_read_ok ( redis_sock ) == SUCCESS ) &&
2154
- ( redis_sock_read_cmp ( redis_sock , id , idlen ) == SUCCESS ) ;
2155
-
2144
+ if (redis_sock_write (redis_sock , cmd .c , cmd .len ) < 0 ) {
2145
+ smart_string_free ( & cmd );
2146
+ goto failure ;
2147
+ }
2156
2148
smart_string_free (& cmd );
2157
- return ok ? SUCCESS : FAILURE ;
2149
+
2150
+ if (redis_sock_gets (redis_sock , inbuf , sizeof (inbuf ) - 1 , & len ) < 0 ) {
2151
+ goto failure ;
2152
+ }
2153
+
2154
+ if (auth ) {
2155
+ if (strncmp (inbuf , "+OK" , 3 ) == 0 || strncmp (inbuf , "-ERR Client sent AUTH" , 21 ) == 0 ) {
2156
+ /* successfully authenticated or authentication isn't required */
2157
+ if (redis_sock_gets (redis_sock , inbuf , sizeof (inbuf ) - 1 , & len ) < 0 ) {
2158
+ goto failure ;
2159
+ }
2160
+ } else if (strncmp (inbuf , "-NOAUTH" , 7 ) == 0 ) {
2161
+ /* connection is fine but authentication failed, next command must fails too */
2162
+ if (redis_sock_gets (redis_sock , inbuf , sizeof (inbuf ) - 1 , & len ) < 0 || strncmp (inbuf , "-NOAUTH" , 7 ) != 0 ) {
2163
+ goto failure ;
2164
+ }
2165
+ return SUCCESS ;
2166
+ } else {
2167
+ goto failure ;
2168
+ }
2169
+ redis_sock -> status = REDIS_SOCK_STATUS_READY ;
2170
+ } else {
2171
+ if (strncmp (inbuf , "-NOAUTH" , 7 ) == 0 ) {
2172
+ /* connection is fine but authentication required */
2173
+ return SUCCESS ;
2174
+ }
2175
+ }
2176
+
2177
+ /* check echo response */
2178
+ if (* inbuf != TYPE_BULK || atoi (inbuf + 1 ) != idlen ||
2179
+ redis_sock_gets (redis_sock , inbuf , sizeof (inbuf ) - 1 , & len ) < 0 ||
2180
+ strncmp (inbuf , id , idlen ) != 0
2181
+ ) {
2182
+ goto failure ;
2183
+ }
2184
+
2185
+ return SUCCESS ;
2186
+ failure :
2187
+ redis_sock -> status = REDIS_SOCK_STATUS_DISCONNECTED ;
2188
+ if (redis_sock -> stream ) {
2189
+ php_stream_pclose (redis_sock -> stream );
2190
+ redis_sock -> stream = NULL ;
2191
+ }
2192
+ return FAILURE ;
2158
2193
}
2159
2194
2160
2195
/**
@@ -2207,11 +2242,7 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock)
2207
2242
zend_llist_remove_tail (& p -> list );
2208
2243
2209
2244
if (redis_sock_check_liveness (redis_sock ) == SUCCESS ) {
2210
- redis_sock -> status = REDIS_SOCK_STATUS_READY ;
2211
2245
return SUCCESS ;
2212
- } else if (redis_sock -> stream ) {
2213
- php_stream_pclose (redis_sock -> stream );
2214
- redis_sock -> stream = NULL ;
2215
2246
}
2216
2247
p -> nb_active -- ;
2217
2248
}
0 commit comments