redis-client 0.3.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/Gemfile +1 -2
  4. data/Gemfile.lock +1 -2
  5. data/README.md +13 -17
  6. data/Rakefile +41 -22
  7. data/lib/redis_client/command_builder.rb +8 -0
  8. data/lib/redis_client/config.rb +13 -5
  9. data/lib/redis_client/connection_mixin.rb +2 -0
  10. data/lib/redis_client/version.rb +1 -1
  11. data/lib/redis_client.rb +31 -15
  12. data/redis-client.gemspec +2 -4
  13. metadata +6 -56
  14. data/.rubocop.yml +0 -191
  15. data/ext/redis_client/hiredis/export.clang +0 -2
  16. data/ext/redis_client/hiredis/export.gcc +0 -7
  17. data/ext/redis_client/hiredis/extconf.rb +0 -69
  18. data/ext/redis_client/hiredis/hiredis_connection.c +0 -708
  19. data/ext/redis_client/hiredis/vendor/.gitignore +0 -9
  20. data/ext/redis_client/hiredis/vendor/.travis.yml +0 -131
  21. data/ext/redis_client/hiredis/vendor/CHANGELOG.md +0 -364
  22. data/ext/redis_client/hiredis/vendor/CMakeLists.txt +0 -165
  23. data/ext/redis_client/hiredis/vendor/COPYING +0 -29
  24. data/ext/redis_client/hiredis/vendor/Makefile +0 -308
  25. data/ext/redis_client/hiredis/vendor/README.md +0 -664
  26. data/ext/redis_client/hiredis/vendor/adapters/ae.h +0 -130
  27. data/ext/redis_client/hiredis/vendor/adapters/glib.h +0 -156
  28. data/ext/redis_client/hiredis/vendor/adapters/ivykis.h +0 -84
  29. data/ext/redis_client/hiredis/vendor/adapters/libev.h +0 -179
  30. data/ext/redis_client/hiredis/vendor/adapters/libevent.h +0 -175
  31. data/ext/redis_client/hiredis/vendor/adapters/libuv.h +0 -117
  32. data/ext/redis_client/hiredis/vendor/adapters/macosx.h +0 -115
  33. data/ext/redis_client/hiredis/vendor/adapters/qt.h +0 -135
  34. data/ext/redis_client/hiredis/vendor/alloc.c +0 -86
  35. data/ext/redis_client/hiredis/vendor/alloc.h +0 -91
  36. data/ext/redis_client/hiredis/vendor/appveyor.yml +0 -24
  37. data/ext/redis_client/hiredis/vendor/async.c +0 -887
  38. data/ext/redis_client/hiredis/vendor/async.h +0 -147
  39. data/ext/redis_client/hiredis/vendor/async_private.h +0 -75
  40. data/ext/redis_client/hiredis/vendor/dict.c +0 -352
  41. data/ext/redis_client/hiredis/vendor/dict.h +0 -126
  42. data/ext/redis_client/hiredis/vendor/fmacros.h +0 -12
  43. data/ext/redis_client/hiredis/vendor/hiredis-config.cmake.in +0 -13
  44. data/ext/redis_client/hiredis/vendor/hiredis.c +0 -1174
  45. data/ext/redis_client/hiredis/vendor/hiredis.h +0 -336
  46. data/ext/redis_client/hiredis/vendor/hiredis.pc.in +0 -12
  47. data/ext/redis_client/hiredis/vendor/hiredis_ssl-config.cmake.in +0 -13
  48. data/ext/redis_client/hiredis/vendor/hiredis_ssl.h +0 -157
  49. data/ext/redis_client/hiredis/vendor/hiredis_ssl.pc.in +0 -12
  50. data/ext/redis_client/hiredis/vendor/net.c +0 -612
  51. data/ext/redis_client/hiredis/vendor/net.h +0 -56
  52. data/ext/redis_client/hiredis/vendor/read.c +0 -739
  53. data/ext/redis_client/hiredis/vendor/read.h +0 -129
  54. data/ext/redis_client/hiredis/vendor/sds.c +0 -1289
  55. data/ext/redis_client/hiredis/vendor/sds.h +0 -278
  56. data/ext/redis_client/hiredis/vendor/sdsalloc.h +0 -44
  57. data/ext/redis_client/hiredis/vendor/sockcompat.c +0 -248
  58. data/ext/redis_client/hiredis/vendor/sockcompat.h +0 -92
  59. data/ext/redis_client/hiredis/vendor/ssl.c +0 -544
  60. data/ext/redis_client/hiredis/vendor/test.c +0 -1401
  61. data/ext/redis_client/hiredis/vendor/test.sh +0 -78
  62. data/ext/redis_client/hiredis/vendor/win32.h +0 -56
  63. data/lib/redis_client/hiredis_connection.rb +0 -93
@@ -1,544 +0,0 @@
1
- /*
2
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
3
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
4
- * Copyright (c) 2019, Redis Labs
5
- *
6
- * All rights reserved.
7
- *
8
- * Redistribution and use in source and binary forms, with or without
9
- * modification, are permitted provided that the following conditions are met:
10
- *
11
- * * Redistributions of source code must retain the above copyright notice,
12
- * this list of conditions and the following disclaimer.
13
- * * Redistributions in binary form must reproduce the above copyright
14
- * notice, this list of conditions and the following disclaimer in the
15
- * documentation and/or other materials provided with the distribution.
16
- * * Neither the name of Redis nor the names of its contributors may be used
17
- * to endorse or promote products derived from this software without
18
- * specific prior written permission.
19
- *
20
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
- * POSSIBILITY OF SUCH DAMAGE.
31
- */
32
-
33
- #include "hiredis.h"
34
- #include "async.h"
35
-
36
- #include <assert.h>
37
- #include <errno.h>
38
- #include <string.h>
39
- #ifdef _WIN32
40
- #include <windows.h>
41
- #else
42
- #include <pthread.h>
43
- #endif
44
-
45
- #include <openssl/ssl.h>
46
- #include <openssl/err.h>
47
-
48
- #include "win32.h"
49
- #include "async_private.h"
50
- #include "hiredis_ssl.h"
51
-
52
- void __redisSetError(redisContext *c, int type, const char *str);
53
-
54
- struct redisSSLContext {
55
- /* Associated OpenSSL SSL_CTX as created by redisCreateSSLContext() */
56
- SSL_CTX *ssl_ctx;
57
-
58
- /* Requested SNI, or NULL */
59
- char *server_name;
60
- };
61
-
62
- /* Forward declaration */
63
- redisContextFuncs redisContextSSLFuncs;
64
-
65
- /**
66
- * OpenSSL global initialization and locking handling callbacks.
67
- * Note that this is only required for OpenSSL < 1.1.0.
68
- */
69
-
70
- #if OPENSSL_VERSION_NUMBER < 0x10100000L
71
- #define HIREDIS_USE_CRYPTO_LOCKS
72
- #endif
73
-
74
- #ifdef HIREDIS_USE_CRYPTO_LOCKS
75
- #ifdef _WIN32
76
- typedef CRITICAL_SECTION sslLockType;
77
- static void sslLockInit(sslLockType* l) {
78
- InitializeCriticalSection(l);
79
- }
80
- static void sslLockAcquire(sslLockType* l) {
81
- EnterCriticalSection(l);
82
- }
83
- static void sslLockRelease(sslLockType* l) {
84
- LeaveCriticalSection(l);
85
- }
86
- #else
87
- typedef pthread_mutex_t sslLockType;
88
- static void sslLockInit(sslLockType *l) {
89
- pthread_mutex_init(l, NULL);
90
- }
91
- static void sslLockAcquire(sslLockType *l) {
92
- pthread_mutex_lock(l);
93
- }
94
- static void sslLockRelease(sslLockType *l) {
95
- pthread_mutex_unlock(l);
96
- }
97
- #endif
98
-
99
- static sslLockType* ossl_locks;
100
-
101
- static void opensslDoLock(int mode, int lkid, const char *f, int line) {
102
- sslLockType *l = ossl_locks + lkid;
103
-
104
- if (mode & CRYPTO_LOCK) {
105
- sslLockAcquire(l);
106
- } else {
107
- sslLockRelease(l);
108
- }
109
-
110
- (void)f;
111
- (void)line;
112
- }
113
-
114
- static int initOpensslLocks(void) {
115
- unsigned ii, nlocks;
116
- if (CRYPTO_get_locking_callback() != NULL) {
117
- /* Someone already set the callback before us. Don't destroy it! */
118
- return REDIS_OK;
119
- }
120
- nlocks = CRYPTO_num_locks();
121
- ossl_locks = hi_malloc(sizeof(*ossl_locks) * nlocks);
122
- if (ossl_locks == NULL)
123
- return REDIS_ERR;
124
-
125
- for (ii = 0; ii < nlocks; ii++) {
126
- sslLockInit(ossl_locks + ii);
127
- }
128
- CRYPTO_set_locking_callback(opensslDoLock);
129
- return REDIS_OK;
130
- }
131
- #endif /* HIREDIS_USE_CRYPTO_LOCKS */
132
-
133
- int redisInitOpenSSL(void)
134
- {
135
- SSL_library_init();
136
- #ifdef HIREDIS_USE_CRYPTO_LOCKS
137
- initOpensslLocks();
138
- #endif
139
-
140
- return REDIS_OK;
141
- }
142
-
143
- static int maybeCheckWant(redisSSL *rssl, int rv) {
144
- /**
145
- * If the error is WANT_READ or WANT_WRITE, the appropriate flags are set
146
- * and true is returned. False is returned otherwise
147
- */
148
- if (rv == SSL_ERROR_WANT_READ) {
149
- rssl->wantRead = 1;
150
- return 1;
151
- } else if (rv == SSL_ERROR_WANT_WRITE) {
152
- rssl->pendingWrite = 1;
153
- return 1;
154
- } else {
155
- return 0;
156
- }
157
- }
158
-
159
- /**
160
- * redisSSLContext helper context destruction.
161
- */
162
-
163
- const char *redisSSLContextGetError(redisSSLContextError error)
164
- {
165
- switch (error) {
166
- case REDIS_SSL_CTX_NONE:
167
- return "No Error";
168
- case REDIS_SSL_CTX_CREATE_FAILED:
169
- return "Failed to create OpenSSL SSL_CTX";
170
- case REDIS_SSL_CTX_CERT_KEY_REQUIRED:
171
- return "Client cert and key must both be specified or skipped";
172
- case REDIS_SSL_CTX_CA_CERT_LOAD_FAILED:
173
- return "Failed to load CA Certificate or CA Path";
174
- case REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED:
175
- return "Failed to load client certificate";
176
- case REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED:
177
- return "Failed to load private key";
178
- default:
179
- return "Unknown error code";
180
- }
181
- }
182
-
183
- void redisFreeSSLContext(redisSSLContext *ctx)
184
- {
185
- if (!ctx)
186
- return;
187
-
188
- if (ctx->server_name) {
189
- hi_free(ctx->server_name);
190
- ctx->server_name = NULL;
191
- }
192
-
193
- if (ctx->ssl_ctx) {
194
- SSL_CTX_free(ctx->ssl_ctx);
195
- ctx->ssl_ctx = NULL;
196
- }
197
-
198
- hi_free(ctx);
199
- }
200
-
201
-
202
- /**
203
- * redisSSLContext helper context initialization.
204
- */
205
-
206
- redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
207
- const char *cert_filename, const char *private_key_filename,
208
- const char *server_name, redisSSLContextError *error)
209
- {
210
- redisSSLContext *ctx = hi_calloc(1, sizeof(redisSSLContext));
211
- if (ctx == NULL)
212
- goto error;
213
-
214
- ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
215
- if (!ctx->ssl_ctx) {
216
- if (error) *error = REDIS_SSL_CTX_CREATE_FAILED;
217
- goto error;
218
- }
219
-
220
- SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
221
- SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL);
222
-
223
- if ((cert_filename != NULL && private_key_filename == NULL) ||
224
- (private_key_filename != NULL && cert_filename == NULL)) {
225
- if (error) *error = REDIS_SSL_CTX_CERT_KEY_REQUIRED;
226
- goto error;
227
- }
228
-
229
- if (capath || cacert_filename) {
230
- if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cacert_filename, capath)) {
231
- if (error) *error = REDIS_SSL_CTX_CA_CERT_LOAD_FAILED;
232
- goto error;
233
- }
234
- }
235
-
236
- if (cert_filename) {
237
- if (!SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, cert_filename)) {
238
- if (error) *error = REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED;
239
- goto error;
240
- }
241
- if (!SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, private_key_filename, SSL_FILETYPE_PEM)) {
242
- if (error) *error = REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED;
243
- goto error;
244
- }
245
- }
246
-
247
- if (server_name)
248
- ctx->server_name = hi_strdup(server_name);
249
-
250
- return ctx;
251
-
252
- error:
253
- redisFreeSSLContext(ctx);
254
- return NULL;
255
- }
256
-
257
- int redisInitiateSSLContinue(redisContext *c) {
258
- if (!c->privctx) {
259
- __redisSetError(c, REDIS_ERR_OTHER, "redisContext is not associated");
260
- return REDIS_ERR;
261
- }
262
-
263
- redisSSL *rssl = (redisSSL *)c->privctx;
264
- ERR_clear_error();
265
- int rv = SSL_connect(rssl->ssl);
266
- if (rv == 1) {
267
- c->privctx = rssl;
268
- return REDIS_OK;
269
- }
270
-
271
- rv = SSL_get_error(rssl->ssl, rv);
272
- if (((c->flags & REDIS_BLOCK) == 0) &&
273
- (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) {
274
- maybeCheckWant(rssl, rv);
275
- c->privctx = rssl;
276
- return REDIS_OK;
277
- }
278
-
279
- if (c->err == 0) {
280
- char err[512];
281
- if (rv == SSL_ERROR_SYSCALL)
282
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno));
283
- else {
284
- unsigned long e = ERR_peek_last_error();
285
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",
286
- ERR_reason_error_string(e));
287
- }
288
- __redisSetError(c, REDIS_ERR_IO, err);
289
- }
290
- return REDIS_ERR;
291
- }
292
-
293
- /**
294
- * SSL Connection initialization.
295
- */
296
-
297
-
298
- static int redisSSLConnect(redisContext *c, SSL *ssl) {
299
- if (c->privctx) {
300
- __redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated");
301
- return REDIS_ERR;
302
- }
303
-
304
- redisSSL *rssl = hi_calloc(1, sizeof(redisSSL));
305
- if (rssl == NULL) {
306
- __redisSetError(c, REDIS_ERR_OOM, "Out of memory");
307
- return REDIS_ERR;
308
- }
309
-
310
- c->funcs = &redisContextSSLFuncs;
311
- rssl->ssl = ssl;
312
-
313
- SSL_set_mode(rssl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
314
- SSL_set_fd(rssl->ssl, c->fd);
315
- SSL_set_connect_state(rssl->ssl);
316
-
317
- ERR_clear_error();
318
- int rv = SSL_connect(rssl->ssl);
319
- if (rv == 1) {
320
- c->privctx = rssl;
321
- return REDIS_OK;
322
- }
323
-
324
- rv = SSL_get_error(rssl->ssl, rv);
325
- if (((c->flags & REDIS_BLOCK) == 0) &&
326
- (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) {
327
- maybeCheckWant(rssl, rv);
328
- c->privctx = rssl;
329
- return REDIS_OK;
330
- }
331
-
332
- if (c->err == 0) {
333
- char err[512];
334
- if (rv == SSL_ERROR_SYSCALL)
335
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno));
336
- else {
337
- unsigned long e = ERR_peek_last_error();
338
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",
339
- ERR_reason_error_string(e));
340
- }
341
- __redisSetError(c, REDIS_ERR_IO, err);
342
- }
343
-
344
- hi_free(rssl);
345
- return REDIS_ERR;
346
- }
347
-
348
- redisSSL *redisGetSSLSocket(redisContext *c) {
349
- return c->privctx;
350
- }
351
-
352
- /**
353
- * A wrapper around redisSSLConnect() for users who manage their own context and
354
- * create their own SSL object.
355
- */
356
-
357
- int redisInitiateSSL(redisContext *c, SSL *ssl) {
358
- return redisSSLConnect(c, ssl);
359
- }
360
-
361
- /**
362
- * A wrapper around redisSSLConnect() for users who use redisSSLContext and don't
363
- * manage their own SSL objects.
364
- */
365
-
366
- int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx)
367
- {
368
- if (!c || !redis_ssl_ctx)
369
- return REDIS_ERR;
370
-
371
- /* We want to verify that redisSSLConnect() won't fail on this, as it will
372
- * not own the SSL object in that case and we'll end up leaking.
373
- */
374
- if (c->privctx)
375
- return REDIS_ERR;
376
-
377
- SSL *ssl = SSL_new(redis_ssl_ctx->ssl_ctx);
378
- if (!ssl) {
379
- __redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance");
380
- goto error;
381
- }
382
-
383
- if (redis_ssl_ctx->server_name) {
384
- if (!SSL_set_tlsext_host_name(ssl, redis_ssl_ctx->server_name)) {
385
- __redisSetError(c, REDIS_ERR_OTHER, "Failed to set server_name/SNI");
386
- goto error;
387
- }
388
- }
389
-
390
- return redisSSLConnect(c, ssl);
391
-
392
- error:
393
- if (ssl)
394
- SSL_free(ssl);
395
- return REDIS_ERR;
396
- }
397
-
398
- /**
399
- * Implementation of redisContextFuncs for SSL connections.
400
- */
401
-
402
- static void redisSSLFree(void *privctx){
403
- redisSSL *rsc = privctx;
404
-
405
- if (!rsc) return;
406
- if (rsc->ssl) {
407
- SSL_free(rsc->ssl);
408
- rsc->ssl = NULL;
409
- }
410
- hi_free(rsc);
411
- }
412
-
413
- static ssize_t redisSSLRead(redisContext *c, char *buf, size_t bufcap) {
414
- redisSSL *rssl = c->privctx;
415
-
416
- int nread = SSL_read(rssl->ssl, buf, bufcap);
417
- if (nread > 0) {
418
- return nread;
419
- } else if (nread == 0) {
420
- __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection");
421
- return -1;
422
- } else {
423
- int err = SSL_get_error(rssl->ssl, nread);
424
- if (c->flags & REDIS_BLOCK) {
425
- /**
426
- * In blocking mode, we should never end up in a situation where
427
- * we get an error without it being an actual error, except
428
- * in the case of EINTR, which can be spuriously received from
429
- * debuggers or whatever.
430
- */
431
- if (errno == EINTR) {
432
- return 0;
433
- } else {
434
- const char *msg = NULL;
435
- if (errno == EAGAIN) {
436
- msg = "Resource temporarily unavailable";
437
- }
438
- __redisSetError(c, REDIS_ERR_IO, msg);
439
- return -1;
440
- }
441
- }
442
-
443
- /**
444
- * We can very well get an EWOULDBLOCK/EAGAIN, however
445
- */
446
- if (maybeCheckWant(rssl, err)) {
447
- return 0;
448
- } else {
449
- __redisSetError(c, REDIS_ERR_IO, NULL);
450
- return -1;
451
- }
452
- }
453
- }
454
-
455
- static ssize_t redisSSLWrite(redisContext *c) {
456
- redisSSL *rssl = c->privctx;
457
-
458
- size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf);
459
- int rv = SSL_write(rssl->ssl, c->obuf, len);
460
-
461
- if (rv > 0) {
462
- rssl->lastLen = 0;
463
- } else if (rv < 0) {
464
- rssl->lastLen = len;
465
-
466
- int err = SSL_get_error(rssl->ssl, rv);
467
- if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) {
468
- return 0;
469
- } else {
470
- __redisSetError(c, REDIS_ERR_IO, NULL);
471
- return -1;
472
- }
473
- }
474
- return rv;
475
- }
476
-
477
- static void redisSSLAsyncRead(redisAsyncContext *ac) {
478
- int rv;
479
- redisSSL *rssl = ac->c.privctx;
480
- redisContext *c = &ac->c;
481
-
482
- rssl->wantRead = 0;
483
-
484
- if (rssl->pendingWrite) {
485
- int done;
486
-
487
- /* This is probably just a write event */
488
- rssl->pendingWrite = 0;
489
- rv = redisBufferWrite(c, &done);
490
- if (rv == REDIS_ERR) {
491
- __redisAsyncDisconnect(ac);
492
- return;
493
- } else if (!done) {
494
- _EL_ADD_WRITE(ac);
495
- }
496
- }
497
-
498
- rv = redisBufferRead(c);
499
- if (rv == REDIS_ERR) {
500
- __redisAsyncDisconnect(ac);
501
- } else {
502
- _EL_ADD_READ(ac);
503
- redisProcessCallbacks(ac);
504
- }
505
- }
506
-
507
- static void redisSSLAsyncWrite(redisAsyncContext *ac) {
508
- int rv, done = 0;
509
- redisSSL *rssl = ac->c.privctx;
510
- redisContext *c = &ac->c;
511
-
512
- rssl->pendingWrite = 0;
513
- rv = redisBufferWrite(c, &done);
514
- if (rv == REDIS_ERR) {
515
- __redisAsyncDisconnect(ac);
516
- return;
517
- }
518
-
519
- if (!done) {
520
- if (rssl->wantRead) {
521
- /* Need to read-before-write */
522
- rssl->pendingWrite = 1;
523
- _EL_DEL_WRITE(ac);
524
- } else {
525
- /* No extra reads needed, just need to write more */
526
- _EL_ADD_WRITE(ac);
527
- }
528
- } else {
529
- /* Already done! */
530
- _EL_DEL_WRITE(ac);
531
- }
532
-
533
- /* Always reschedule a read */
534
- _EL_ADD_READ(ac);
535
- }
536
-
537
- redisContextFuncs redisContextSSLFuncs = {
538
- .free_privctx = redisSSLFree,
539
- .async_read = redisSSLAsyncRead,
540
- .async_write = redisSSLAsyncWrite,
541
- .read = redisSSLRead,
542
- .write = redisSSLWrite
543
- };
544
-