2
0

hiredis.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  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. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * * Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * * Neither the name of Redis nor the names of its contributors may be used
  16. * to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "fmacros.h"
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <unistd.h>
  35. #include <assert.h>
  36. #include <errno.h>
  37. #include <ctype.h>
  38. #include "hiredis.h"
  39. #include "net.h"
  40. #include "sds.h"
  41. static redisReply *createReplyObject(int type);
  42. static void *createStringObject(const redisReadTask *task, char *str, size_t len);
  43. static void *createArrayObject(const redisReadTask *task, int elements);
  44. static void *createIntegerObject(const redisReadTask *task, long long value);
  45. static void *createNilObject(const redisReadTask *task);
  46. /* Default set of functions to build the reply. Keep in mind that such a
  47. * function returning NULL is interpreted as OOM. */
  48. static redisReplyObjectFunctions defaultFunctions = {
  49. createStringObject,
  50. createArrayObject,
  51. createIntegerObject,
  52. createNilObject,
  53. freeReplyObject
  54. };
  55. /* Create a reply object */
  56. static redisReply *createReplyObject(int type) {
  57. redisReply *r = calloc(1,sizeof(*r));
  58. if (r == NULL)
  59. return NULL;
  60. r->type = type;
  61. return r;
  62. }
  63. /* Free a reply object */
  64. void freeReplyObject(void *reply) {
  65. redisReply *r = reply;
  66. size_t j;
  67. switch(r->type) {
  68. case REDIS_REPLY_INTEGER:
  69. break; /* Nothing to free */
  70. case REDIS_REPLY_ARRAY:
  71. if (r->element != NULL) {
  72. for (j = 0; j < r->elements; j++)
  73. if (r->element[j] != NULL)
  74. freeReplyObject(r->element[j]);
  75. free(r->element);
  76. }
  77. break;
  78. case REDIS_REPLY_ERROR:
  79. case REDIS_REPLY_STATUS:
  80. case REDIS_REPLY_STRING:
  81. if (r->str != NULL)
  82. free(r->str);
  83. break;
  84. }
  85. free(r);
  86. }
  87. static void *createStringObject(const redisReadTask *task, char *str, size_t len) {
  88. redisReply *r, *parent;
  89. char *buf;
  90. r = createReplyObject(task->type);
  91. if (r == NULL)
  92. return NULL;
  93. buf = malloc(len+1);
  94. if (buf == NULL) {
  95. freeReplyObject(r);
  96. return NULL;
  97. }
  98. assert(task->type == REDIS_REPLY_ERROR ||
  99. task->type == REDIS_REPLY_STATUS ||
  100. task->type == REDIS_REPLY_STRING);
  101. /* Copy string value */
  102. memcpy(buf,str,len);
  103. buf[len] = '\0';
  104. r->str = buf;
  105. r->len = len;
  106. if (task->parent) {
  107. parent = task->parent->obj;
  108. assert(parent->type == REDIS_REPLY_ARRAY);
  109. parent->element[task->idx] = r;
  110. }
  111. return r;
  112. }
  113. static void *createArrayObject(const redisReadTask *task, int elements) {
  114. redisReply *r, *parent;
  115. r = createReplyObject(REDIS_REPLY_ARRAY);
  116. if (r == NULL)
  117. return NULL;
  118. if (elements > 0) {
  119. r->element = calloc(elements,sizeof(redisReply*));
  120. if (r->element == NULL) {
  121. freeReplyObject(r);
  122. return NULL;
  123. }
  124. }
  125. r->elements = elements;
  126. if (task->parent) {
  127. parent = task->parent->obj;
  128. assert(parent->type == REDIS_REPLY_ARRAY);
  129. parent->element[task->idx] = r;
  130. }
  131. return r;
  132. }
  133. static void *createIntegerObject(const redisReadTask *task, long long value) {
  134. redisReply *r, *parent;
  135. r = createReplyObject(REDIS_REPLY_INTEGER);
  136. if (r == NULL)
  137. return NULL;
  138. r->integer = value;
  139. if (task->parent) {
  140. parent = task->parent->obj;
  141. assert(parent->type == REDIS_REPLY_ARRAY);
  142. parent->element[task->idx] = r;
  143. }
  144. return r;
  145. }
  146. static void *createNilObject(const redisReadTask *task) {
  147. redisReply *r, *parent;
  148. r = createReplyObject(REDIS_REPLY_NIL);
  149. if (r == NULL)
  150. return NULL;
  151. if (task->parent) {
  152. parent = task->parent->obj;
  153. assert(parent->type == REDIS_REPLY_ARRAY);
  154. parent->element[task->idx] = r;
  155. }
  156. return r;
  157. }
  158. static void __redisReaderSetError(redisReader *r, int type, const char *str) {
  159. size_t len;
  160. if (r->reply != NULL && r->fn && r->fn->freeObject) {
  161. r->fn->freeObject(r->reply);
  162. r->reply = NULL;
  163. }
  164. /* Clear input buffer on errors. */
  165. if (r->buf != NULL) {
  166. sdsfree(r->buf);
  167. r->buf = NULL;
  168. r->pos = r->len = 0;
  169. }
  170. /* Reset task stack. */
  171. r->ridx = -1;
  172. /* Set error. */
  173. r->err = type;
  174. len = strlen(str);
  175. len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1);
  176. memcpy(r->errstr,str,len);
  177. r->errstr[len] = '\0';
  178. }
  179. static size_t chrtos(char *buf, size_t size, char byte) {
  180. size_t len = 0;
  181. switch(byte) {
  182. case '\\':
  183. case '"':
  184. len = snprintf(buf,size,"\"\\%c\"",byte);
  185. break;
  186. case '\n': len = snprintf(buf,size,"\"\\n\""); break;
  187. case '\r': len = snprintf(buf,size,"\"\\r\""); break;
  188. case '\t': len = snprintf(buf,size,"\"\\t\""); break;
  189. case '\a': len = snprintf(buf,size,"\"\\a\""); break;
  190. case '\b': len = snprintf(buf,size,"\"\\b\""); break;
  191. default:
  192. if (isprint(byte))
  193. len = snprintf(buf,size,"\"%c\"",byte);
  194. else
  195. len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte);
  196. break;
  197. }
  198. return len;
  199. }
  200. static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) {
  201. char cbuf[8], sbuf[128];
  202. chrtos(cbuf,sizeof(cbuf),byte);
  203. snprintf(sbuf,sizeof(sbuf),
  204. "Protocol error, got %s as reply type byte", cbuf);
  205. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf);
  206. }
  207. static void __redisReaderSetErrorOOM(redisReader *r) {
  208. __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory");
  209. }
  210. static char *readBytes(redisReader *r, unsigned int bytes) {
  211. char *p;
  212. if (r->len-r->pos >= bytes) {
  213. p = r->buf+r->pos;
  214. r->pos += bytes;
  215. return p;
  216. }
  217. return NULL;
  218. }
  219. /* Find pointer to \r\n. */
  220. static char *seekNewline(char *s, size_t len) {
  221. int pos = 0;
  222. int _len = len-1;
  223. /* Position should be < len-1 because the character at "pos" should be
  224. * followed by a \n. Note that strchr cannot be used because it doesn't
  225. * allow to search a limited length and the buffer that is being searched
  226. * might not have a trailing NULL character. */
  227. while (pos < _len) {
  228. while(pos < _len && s[pos] != '\r') pos++;
  229. if (s[pos] != '\r') {
  230. /* Not found. */
  231. return NULL;
  232. } else {
  233. if (s[pos+1] == '\n') {
  234. /* Found. */
  235. return s+pos;
  236. } else {
  237. /* Continue searching. */
  238. pos++;
  239. }
  240. }
  241. }
  242. return NULL;
  243. }
  244. /* Read a long long value starting at *s, under the assumption that it will be
  245. * terminated by \r\n. Ambiguously returns -1 for unexpected input. */
  246. static long long readLongLong(char *s) {
  247. long long v = 0;
  248. int dec, mult = 1;
  249. char c;
  250. if (*s == '-') {
  251. mult = -1;
  252. s++;
  253. } else if (*s == '+') {
  254. mult = 1;
  255. s++;
  256. }
  257. while ((c = *(s++)) != '\r') {
  258. dec = c - '0';
  259. if (dec >= 0 && dec < 10) {
  260. v *= 10;
  261. v += dec;
  262. } else {
  263. /* Should not happen... */
  264. return -1;
  265. }
  266. }
  267. return mult*v;
  268. }
  269. static char *readLine(redisReader *r, int *_len) {
  270. char *p, *s;
  271. int len;
  272. p = r->buf+r->pos;
  273. s = seekNewline(p,(r->len-r->pos));
  274. if (s != NULL) {
  275. len = s-(r->buf+r->pos);
  276. r->pos += len+2; /* skip \r\n */
  277. if (_len) *_len = len;
  278. return p;
  279. }
  280. return NULL;
  281. }
  282. static void moveToNextTask(redisReader *r) {
  283. redisReadTask *cur, *prv;
  284. while (r->ridx >= 0) {
  285. /* Return a.s.a.p. when the stack is now empty. */
  286. if (r->ridx == 0) {
  287. r->ridx--;
  288. return;
  289. }
  290. cur = &(r->rstack[r->ridx]);
  291. prv = &(r->rstack[r->ridx-1]);
  292. assert(prv->type == REDIS_REPLY_ARRAY);
  293. if (cur->idx == prv->elements-1) {
  294. r->ridx--;
  295. } else {
  296. /* Reset the type because the next item can be anything */
  297. assert(cur->idx < prv->elements);
  298. cur->type = -1;
  299. cur->elements = -1;
  300. cur->idx++;
  301. return;
  302. }
  303. }
  304. }
  305. static int processLineItem(redisReader *r) {
  306. redisReadTask *cur = &(r->rstack[r->ridx]);
  307. void *obj;
  308. char *p;
  309. int len;
  310. if ((p = readLine(r,&len)) != NULL) {
  311. if (cur->type == REDIS_REPLY_INTEGER) {
  312. if (r->fn && r->fn->createInteger)
  313. obj = r->fn->createInteger(cur,readLongLong(p));
  314. else
  315. obj = (void*)REDIS_REPLY_INTEGER;
  316. } else {
  317. /* Type will be error or status. */
  318. if (r->fn && r->fn->createString)
  319. obj = r->fn->createString(cur,p,len);
  320. else
  321. obj = (void*)(size_t)(cur->type);
  322. }
  323. if (obj == NULL) {
  324. __redisReaderSetErrorOOM(r);
  325. return REDIS_ERR;
  326. }
  327. /* Set reply if this is the root object. */
  328. if (r->ridx == 0) r->reply = obj;
  329. moveToNextTask(r);
  330. return REDIS_OK;
  331. }
  332. return REDIS_ERR;
  333. }
  334. static int processBulkItem(redisReader *r) {
  335. redisReadTask *cur = &(r->rstack[r->ridx]);
  336. void *obj = NULL;
  337. char *p, *s;
  338. long len;
  339. unsigned long bytelen;
  340. int success = 0;
  341. p = r->buf+r->pos;
  342. s = seekNewline(p,r->len-r->pos);
  343. if (s != NULL) {
  344. p = r->buf+r->pos;
  345. bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
  346. len = readLongLong(p);
  347. if (len < 0) {
  348. /* The nil object can always be created. */
  349. if (r->fn && r->fn->createNil)
  350. obj = r->fn->createNil(cur);
  351. else
  352. obj = (void*)REDIS_REPLY_NIL;
  353. success = 1;
  354. } else {
  355. /* Only continue when the buffer contains the entire bulk item. */
  356. bytelen += len+2; /* include \r\n */
  357. if (r->pos+bytelen <= r->len) {
  358. if (r->fn && r->fn->createString)
  359. obj = r->fn->createString(cur,s+2,len);
  360. else
  361. obj = (void*)REDIS_REPLY_STRING;
  362. success = 1;
  363. }
  364. }
  365. /* Proceed when obj was created. */
  366. if (success) {
  367. if (obj == NULL) {
  368. __redisReaderSetErrorOOM(r);
  369. return REDIS_ERR;
  370. }
  371. r->pos += bytelen;
  372. /* Set reply if this is the root object. */
  373. if (r->ridx == 0) r->reply = obj;
  374. moveToNextTask(r);
  375. return REDIS_OK;
  376. }
  377. }
  378. return REDIS_ERR;
  379. }
  380. static int processMultiBulkItem(redisReader *r) {
  381. redisReadTask *cur = &(r->rstack[r->ridx]);
  382. void *obj;
  383. char *p;
  384. long elements;
  385. int root = 0;
  386. /* Set error for nested multi bulks with depth > 7 */
  387. if (r->ridx == 8) {
  388. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  389. "No support for nested multi bulk replies with depth > 7");
  390. return REDIS_ERR;
  391. }
  392. if ((p = readLine(r,NULL)) != NULL) {
  393. elements = readLongLong(p);
  394. root = (r->ridx == 0);
  395. if (elements == -1) {
  396. if (r->fn && r->fn->createNil)
  397. obj = r->fn->createNil(cur);
  398. else
  399. obj = (void*)REDIS_REPLY_NIL;
  400. if (obj == NULL) {
  401. __redisReaderSetErrorOOM(r);
  402. return REDIS_ERR;
  403. }
  404. moveToNextTask(r);
  405. } else {
  406. if (r->fn && r->fn->createArray)
  407. obj = r->fn->createArray(cur,elements);
  408. else
  409. obj = (void*)REDIS_REPLY_ARRAY;
  410. if (obj == NULL) {
  411. __redisReaderSetErrorOOM(r);
  412. return REDIS_ERR;
  413. }
  414. /* Modify task stack when there are more than 0 elements. */
  415. if (elements > 0) {
  416. cur->elements = elements;
  417. cur->obj = obj;
  418. r->ridx++;
  419. r->rstack[r->ridx].type = -1;
  420. r->rstack[r->ridx].elements = -1;
  421. r->rstack[r->ridx].idx = 0;
  422. r->rstack[r->ridx].obj = NULL;
  423. r->rstack[r->ridx].parent = cur;
  424. r->rstack[r->ridx].privdata = r->privdata;
  425. } else {
  426. moveToNextTask(r);
  427. }
  428. }
  429. /* Set reply if this is the root object. */
  430. if (root) r->reply = obj;
  431. return REDIS_OK;
  432. }
  433. return REDIS_ERR;
  434. }
  435. static int processItem(redisReader *r) {
  436. redisReadTask *cur = &(r->rstack[r->ridx]);
  437. char *p;
  438. /* check if we need to read type */
  439. if (cur->type < 0) {
  440. if ((p = readBytes(r,1)) != NULL) {
  441. switch (p[0]) {
  442. case '-':
  443. cur->type = REDIS_REPLY_ERROR;
  444. break;
  445. case '+':
  446. cur->type = REDIS_REPLY_STATUS;
  447. break;
  448. case ':':
  449. cur->type = REDIS_REPLY_INTEGER;
  450. break;
  451. case '$':
  452. cur->type = REDIS_REPLY_STRING;
  453. break;
  454. case '*':
  455. cur->type = REDIS_REPLY_ARRAY;
  456. break;
  457. default:
  458. __redisReaderSetErrorProtocolByte(r,*p);
  459. return REDIS_ERR;
  460. }
  461. } else {
  462. /* could not consume 1 byte */
  463. return REDIS_ERR;
  464. }
  465. }
  466. /* process typed item */
  467. switch(cur->type) {
  468. case REDIS_REPLY_ERROR:
  469. case REDIS_REPLY_STATUS:
  470. case REDIS_REPLY_INTEGER:
  471. return processLineItem(r);
  472. case REDIS_REPLY_STRING:
  473. return processBulkItem(r);
  474. case REDIS_REPLY_ARRAY:
  475. return processMultiBulkItem(r);
  476. default:
  477. assert(NULL);
  478. return REDIS_ERR; /* Avoid warning. */
  479. }
  480. }
  481. redisReader *redisReaderCreate(void) {
  482. redisReader *r;
  483. r = calloc(sizeof(redisReader),1);
  484. if (r == NULL)
  485. return NULL;
  486. r->err = 0;
  487. r->errstr[0] = '\0';
  488. r->fn = &defaultFunctions;
  489. r->buf = sdsempty();
  490. r->maxbuf = REDIS_READER_MAX_BUF;
  491. if (r->buf == NULL) {
  492. free(r);
  493. return NULL;
  494. }
  495. r->ridx = -1;
  496. return r;
  497. }
  498. void redisReaderFree(redisReader *r) {
  499. if (r->reply != NULL && r->fn && r->fn->freeObject)
  500. r->fn->freeObject(r->reply);
  501. if (r->buf != NULL)
  502. sdsfree(r->buf);
  503. free(r);
  504. }
  505. int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
  506. sds newbuf;
  507. /* Return early when this reader is in an erroneous state. */
  508. if (r->err)
  509. return REDIS_ERR;
  510. /* Copy the provided buffer. */
  511. if (buf != NULL && len >= 1) {
  512. /* Destroy internal buffer when it is empty and is quite large. */
  513. if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
  514. sdsfree(r->buf);
  515. r->buf = sdsempty();
  516. r->pos = 0;
  517. /* r->buf should not be NULL since we just free'd a larger one. */
  518. assert(r->buf != NULL);
  519. }
  520. newbuf = sdscatlen(r->buf,buf,len);
  521. if (newbuf == NULL) {
  522. __redisReaderSetErrorOOM(r);
  523. return REDIS_ERR;
  524. }
  525. r->buf = newbuf;
  526. r->len = sdslen(r->buf);
  527. }
  528. return REDIS_OK;
  529. }
  530. int redisReaderGetReply(redisReader *r, void **reply) {
  531. /* Default target pointer to NULL. */
  532. if (reply != NULL)
  533. *reply = NULL;
  534. /* Return early when this reader is in an erroneous state. */
  535. if (r->err)
  536. return REDIS_ERR;
  537. /* When the buffer is empty, there will never be a reply. */
  538. if (r->len == 0)
  539. return REDIS_OK;
  540. /* Set first item to process when the stack is empty. */
  541. if (r->ridx == -1) {
  542. r->rstack[0].type = -1;
  543. r->rstack[0].elements = -1;
  544. r->rstack[0].idx = -1;
  545. r->rstack[0].obj = NULL;
  546. r->rstack[0].parent = NULL;
  547. r->rstack[0].privdata = r->privdata;
  548. r->ridx = 0;
  549. }
  550. /* Process items in reply. */
  551. while (r->ridx >= 0)
  552. if (processItem(r) != REDIS_OK)
  553. break;
  554. /* Return ASAP when an error occurred. */
  555. if (r->err)
  556. return REDIS_ERR;
  557. /* Discard part of the buffer when we've consumed at least 1k, to avoid
  558. * doing unnecessary calls to memmove() in sds.c. */
  559. if (r->pos >= 1024) {
  560. sdsrange(r->buf,r->pos,-1);
  561. r->pos = 0;
  562. r->len = sdslen(r->buf);
  563. }
  564. /* Emit a reply when there is one. */
  565. if (r->ridx == -1) {
  566. if (reply != NULL)
  567. *reply = r->reply;
  568. r->reply = NULL;
  569. }
  570. return REDIS_OK;
  571. }
  572. /* Calculate the number of bytes needed to represent an integer as string. */
  573. static int intlen(int i) {
  574. int len = 0;
  575. if (i < 0) {
  576. len++;
  577. i = -i;
  578. }
  579. do {
  580. len++;
  581. i /= 10;
  582. } while(i);
  583. return len;
  584. }
  585. /* Helper that calculates the bulk length given a certain string length. */
  586. static size_t bulklen(size_t len) {
  587. return 1+intlen(len)+2+len+2;
  588. }
  589. int redisvFormatCommand(char **target, const char *format, va_list ap) {
  590. const char *c = format;
  591. char *cmd = NULL; /* final command */
  592. int pos; /* position in final command */
  593. sds curarg, newarg; /* current argument */
  594. int touched = 0; /* was the current argument touched? */
  595. char **curargv = NULL, **newargv = NULL;
  596. int argc = 0;
  597. int totlen = 0;
  598. int j;
  599. /* Abort if there is not target to set */
  600. if (target == NULL)
  601. return -1;
  602. /* Build the command string accordingly to protocol */
  603. curarg = sdsempty();
  604. if (curarg == NULL)
  605. return -1;
  606. while(*c != '\0') {
  607. if (*c != '%' || c[1] == '\0') {
  608. if (*c == ' ') {
  609. if (touched) {
  610. newargv = realloc(curargv,sizeof(char*)*(argc+1));
  611. if (newargv == NULL) goto err;
  612. curargv = newargv;
  613. curargv[argc++] = curarg;
  614. totlen += bulklen(sdslen(curarg));
  615. /* curarg is put in argv so it can be overwritten. */
  616. curarg = sdsempty();
  617. if (curarg == NULL) goto err;
  618. touched = 0;
  619. }
  620. } else {
  621. newarg = sdscatlen(curarg,c,1);
  622. if (newarg == NULL) goto err;
  623. curarg = newarg;
  624. touched = 1;
  625. }
  626. } else {
  627. char *arg;
  628. size_t size;
  629. /* Set newarg so it can be checked even if it is not touched. */
  630. newarg = curarg;
  631. switch(c[1]) {
  632. case 's':
  633. arg = va_arg(ap,char*);
  634. size = strlen(arg);
  635. if (size > 0)
  636. newarg = sdscatlen(curarg,arg,size);
  637. break;
  638. case 'b':
  639. arg = va_arg(ap,char*);
  640. size = va_arg(ap,size_t);
  641. if (size > 0)
  642. newarg = sdscatlen(curarg,arg,size);
  643. break;
  644. case '%':
  645. newarg = sdscat(curarg,"%");
  646. break;
  647. default:
  648. /* Try to detect printf format */
  649. {
  650. static const char intfmts[] = "diouxX";
  651. char _format[16];
  652. const char *_p = c+1;
  653. size_t _l = 0;
  654. va_list _cpy;
  655. /* Flags */
  656. if (*_p != '\0' && *_p == '#') _p++;
  657. if (*_p != '\0' && *_p == '0') _p++;
  658. if (*_p != '\0' && *_p == '-') _p++;
  659. if (*_p != '\0' && *_p == ' ') _p++;
  660. if (*_p != '\0' && *_p == '+') _p++;
  661. /* Field width */
  662. while (*_p != '\0' && isdigit(*_p)) _p++;
  663. /* Precision */
  664. if (*_p == '.') {
  665. _p++;
  666. while (*_p != '\0' && isdigit(*_p)) _p++;
  667. }
  668. /* Copy va_list before consuming with va_arg */
  669. va_copy(_cpy,ap);
  670. /* Integer conversion (without modifiers) */
  671. if (strchr(intfmts,*_p) != NULL) {
  672. va_arg(ap,int);
  673. goto fmt_valid;
  674. }
  675. /* Double conversion (without modifiers) */
  676. if (strchr("eEfFgGaA",*_p) != NULL) {
  677. va_arg(ap,double);
  678. goto fmt_valid;
  679. }
  680. /* Size: char */
  681. if (_p[0] == 'h' && _p[1] == 'h') {
  682. _p += 2;
  683. if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
  684. va_arg(ap,int); /* char gets promoted to int */
  685. goto fmt_valid;
  686. }
  687. goto fmt_invalid;
  688. }
  689. /* Size: short */
  690. if (_p[0] == 'h') {
  691. _p += 1;
  692. if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
  693. va_arg(ap,int); /* short gets promoted to int */
  694. goto fmt_valid;
  695. }
  696. goto fmt_invalid;
  697. }
  698. /* Size: long long */
  699. if (_p[0] == 'l' && _p[1] == 'l') {
  700. _p += 2;
  701. if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
  702. va_arg(ap,long long);
  703. goto fmt_valid;
  704. }
  705. goto fmt_invalid;
  706. }
  707. /* Size: long */
  708. if (_p[0] == 'l') {
  709. _p += 1;
  710. if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
  711. va_arg(ap,long);
  712. goto fmt_valid;
  713. }
  714. goto fmt_invalid;
  715. }
  716. fmt_invalid:
  717. va_end(_cpy);
  718. goto err;
  719. fmt_valid:
  720. _l = (_p+1)-c;
  721. if (_l < sizeof(_format)-2) {
  722. memcpy(_format,c,_l);
  723. _format[_l] = '\0';
  724. newarg = sdscatvprintf(curarg,_format,_cpy);
  725. /* Update current position (note: outer blocks
  726. * increment c twice so compensate here) */
  727. c = _p-1;
  728. }
  729. va_end(_cpy);
  730. break;
  731. }
  732. }
  733. if (newarg == NULL) goto err;
  734. curarg = newarg;
  735. touched = 1;
  736. c++;
  737. }
  738. c++;
  739. }
  740. /* Add the last argument if needed */
  741. if (touched) {
  742. newargv = realloc(curargv,sizeof(char*)*(argc+1));
  743. if (newargv == NULL) goto err;
  744. curargv = newargv;
  745. curargv[argc++] = curarg;
  746. totlen += bulklen(sdslen(curarg));
  747. } else {
  748. sdsfree(curarg);
  749. }
  750. /* Clear curarg because it was put in curargv or was free'd. */
  751. curarg = NULL;
  752. /* Add bytes needed to hold multi bulk count */
  753. totlen += 1+intlen(argc)+2;
  754. /* Build the command at protocol level */
  755. cmd = malloc(totlen+1);
  756. if (cmd == NULL) goto err;
  757. pos = sprintf(cmd,"*%d\r\n",argc);
  758. for (j = 0; j < argc; j++) {
  759. pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
  760. memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
  761. pos += sdslen(curargv[j]);
  762. sdsfree(curargv[j]);
  763. cmd[pos++] = '\r';
  764. cmd[pos++] = '\n';
  765. }
  766. assert(pos == totlen);
  767. cmd[pos] = '\0';
  768. free(curargv);
  769. *target = cmd;
  770. return totlen;
  771. err:
  772. while(argc--)
  773. sdsfree(curargv[argc]);
  774. free(curargv);
  775. if (curarg != NULL)
  776. sdsfree(curarg);
  777. /* No need to check cmd since it is the last statement that can fail,
  778. * but do it anyway to be as defensive as possible. */
  779. if (cmd != NULL)
  780. free(cmd);
  781. return -1;
  782. }
  783. /* Format a command according to the Redis protocol. This function
  784. * takes a format similar to printf:
  785. *
  786. * %s represents a C null terminated string you want to interpolate
  787. * %b represents a binary safe string
  788. *
  789. * When using %b you need to provide both the pointer to the string
  790. * and the length in bytes. Examples:
  791. *
  792. * len = redisFormatCommand(target, "GET %s", mykey);
  793. * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen);
  794. */
  795. int redisFormatCommand(char **target, const char *format, ...) {
  796. va_list ap;
  797. int len;
  798. va_start(ap,format);
  799. len = redisvFormatCommand(target,format,ap);
  800. va_end(ap);
  801. return len;
  802. }
  803. /* Format a command according to the Redis protocol. This function takes the
  804. * number of arguments, an array with arguments and an array with their
  805. * lengths. If the latter is set to NULL, strlen will be used to compute the
  806. * argument lengths.
  807. */
  808. int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
  809. char *cmd = NULL; /* final command */
  810. int pos; /* position in final command */
  811. size_t len;
  812. int totlen, j;
  813. /* Calculate number of bytes needed for the command */
  814. totlen = 1+intlen(argc)+2;
  815. for (j = 0; j < argc; j++) {
  816. len = argvlen ? argvlen[j] : strlen(argv[j]);
  817. totlen += bulklen(len);
  818. }
  819. /* Build the command at protocol level */
  820. cmd = malloc(totlen+1);
  821. if (cmd == NULL)
  822. return -1;
  823. pos = sprintf(cmd,"*%d\r\n",argc);
  824. for (j = 0; j < argc; j++) {
  825. len = argvlen ? argvlen[j] : strlen(argv[j]);
  826. pos += sprintf(cmd+pos,"$%zu\r\n",len);
  827. memcpy(cmd+pos,argv[j],len);
  828. pos += len;
  829. cmd[pos++] = '\r';
  830. cmd[pos++] = '\n';
  831. }
  832. assert(pos == totlen);
  833. cmd[pos] = '\0';
  834. *target = cmd;
  835. return totlen;
  836. }
  837. void __redisSetError(redisContext *c, int type, const char *str) {
  838. size_t len;
  839. c->err = type;
  840. if (str != NULL) {
  841. len = strlen(str);
  842. len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1);
  843. memcpy(c->errstr,str,len);
  844. c->errstr[len] = '\0';
  845. } else {
  846. /* Only REDIS_ERR_IO may lack a description! */
  847. assert(type == REDIS_ERR_IO);
  848. strerror_r(errno,c->errstr,sizeof(c->errstr));
  849. }
  850. }
  851. static redisContext *redisContextInit(void) {
  852. redisContext *c;
  853. c = calloc(1,sizeof(redisContext));
  854. if (c == NULL)
  855. return NULL;
  856. c->err = 0;
  857. c->errstr[0] = '\0';
  858. c->obuf = sdsempty();
  859. c->reader = redisReaderCreate();
  860. return c;
  861. }
  862. void redisFree(redisContext *c) {
  863. if (c->fd > 0)
  864. close(c->fd);
  865. if (c->obuf != NULL)
  866. sdsfree(c->obuf);
  867. if (c->reader != NULL)
  868. redisReaderFree(c->reader);
  869. free(c);
  870. }
  871. /* Connect to a Redis instance. On error the field error in the returned
  872. * context will be set to the return value of the error function.
  873. * When no set of reply functions is given, the default set will be used. */
  874. redisContext *redisConnect(const char *ip, int port) {
  875. redisContext *c = redisContextInit();
  876. c->flags |= REDIS_BLOCK;
  877. redisContextConnectTcp(c,ip,port,NULL);
  878. return c;
  879. }
  880. redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv) {
  881. redisContext *c = redisContextInit();
  882. c->flags |= REDIS_BLOCK;
  883. redisContextConnectTcp(c,ip,port,&tv);
  884. return c;
  885. }
  886. redisContext *redisConnectNonBlock(const char *ip, int port) {
  887. redisContext *c = redisContextInit();
  888. c->flags &= ~REDIS_BLOCK;
  889. redisContextConnectTcp(c,ip,port,NULL);
  890. return c;
  891. }
  892. redisContext *redisConnectUnix(const char *path) {
  893. redisContext *c = redisContextInit();
  894. c->flags |= REDIS_BLOCK;
  895. redisContextConnectUnix(c,path,NULL);
  896. return c;
  897. }
  898. redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv) {
  899. redisContext *c = redisContextInit();
  900. c->flags |= REDIS_BLOCK;
  901. redisContextConnectUnix(c,path,&tv);
  902. return c;
  903. }
  904. redisContext *redisConnectUnixNonBlock(const char *path) {
  905. redisContext *c = redisContextInit();
  906. c->flags &= ~REDIS_BLOCK;
  907. redisContextConnectUnix(c,path,NULL);
  908. return c;
  909. }
  910. /* Set read/write timeout on a blocking socket. */
  911. int redisSetTimeout(redisContext *c, struct timeval tv) {
  912. if (c->flags & REDIS_BLOCK)
  913. return redisContextSetTimeout(c,tv);
  914. return REDIS_ERR;
  915. }
  916. /* Use this function to handle a read event on the descriptor. It will try
  917. * and read some bytes from the socket and feed them to the reply parser.
  918. *
  919. * After this function is called, you may use redisContextReadReply to
  920. * see if there is a reply available. */
  921. int redisBufferRead(redisContext *c) {
  922. char buf[1024*16];
  923. int nread;
  924. /* Return early when the context has seen an error. */
  925. if (c->err)
  926. return REDIS_ERR;
  927. nread = read(c->fd,buf,sizeof(buf));
  928. if (nread == -1) {
  929. if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
  930. /* Try again later */
  931. } else {
  932. __redisSetError(c,REDIS_ERR_IO,NULL);
  933. return REDIS_ERR;
  934. }
  935. } else if (nread == 0) {
  936. __redisSetError(c,REDIS_ERR_EOF,"Server closed the connection");
  937. return REDIS_ERR;
  938. } else {
  939. if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
  940. __redisSetError(c,c->reader->err,c->reader->errstr);
  941. return REDIS_ERR;
  942. }
  943. }
  944. return REDIS_OK;
  945. }
  946. /* Write the output buffer to the socket.
  947. *
  948. * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
  949. * succesfully written to the socket. When the buffer is empty after the
  950. * write operation, "done" is set to 1 (if given).
  951. *
  952. * Returns REDIS_ERR if an error occured trying to write and sets
  953. * c->errstr to hold the appropriate error string.
  954. */
  955. int redisBufferWrite(redisContext *c, int *done) {
  956. int nwritten;
  957. /* Return early when the context has seen an error. */
  958. if (c->err)
  959. return REDIS_ERR;
  960. if (sdslen(c->obuf) > 0) {
  961. nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
  962. if (nwritten == -1) {
  963. if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
  964. /* Try again later */
  965. } else {
  966. __redisSetError(c,REDIS_ERR_IO,NULL);
  967. return REDIS_ERR;
  968. }
  969. } else if (nwritten > 0) {
  970. if (nwritten == (signed)sdslen(c->obuf)) {
  971. sdsfree(c->obuf);
  972. c->obuf = sdsempty();
  973. } else {
  974. sdsrange(c->obuf,nwritten,-1);
  975. }
  976. }
  977. }
  978. if (done != NULL) *done = (sdslen(c->obuf) == 0);
  979. return REDIS_OK;
  980. }
  981. /* Internal helper function to try and get a reply from the reader,
  982. * or set an error in the context otherwise. */
  983. int redisGetReplyFromReader(redisContext *c, void **reply) {
  984. if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
  985. __redisSetError(c,c->reader->err,c->reader->errstr);
  986. return REDIS_ERR;
  987. }
  988. return REDIS_OK;
  989. }
  990. int redisGetReply(redisContext *c, void **reply) {
  991. int wdone = 0;
  992. void *aux = NULL;
  993. /* Try to read pending replies */
  994. if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
  995. return REDIS_ERR;
  996. /* For the blocking context, flush output buffer and read reply */
  997. if (aux == NULL && c->flags & REDIS_BLOCK) {
  998. /* Write until done */
  999. do {
  1000. if (redisBufferWrite(c,&wdone) == REDIS_ERR)
  1001. return REDIS_ERR;
  1002. } while (!wdone);
  1003. /* Read until there is a reply */
  1004. do {
  1005. if (redisBufferRead(c) == REDIS_ERR)
  1006. return REDIS_ERR;
  1007. if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
  1008. return REDIS_ERR;
  1009. } while (aux == NULL);
  1010. }
  1011. /* Set reply object */
  1012. if (reply != NULL) *reply = aux;
  1013. return REDIS_OK;
  1014. }
  1015. /* Helper function for the redisAppendCommand* family of functions.
  1016. *
  1017. * Write a formatted command to the output buffer. When this family
  1018. * is used, you need to call redisGetReply yourself to retrieve
  1019. * the reply (or replies in pub/sub).
  1020. */
  1021. int __redisAppendCommand(redisContext *c, char *cmd, size_t len) {
  1022. sds newbuf;
  1023. newbuf = sdscatlen(c->obuf,cmd,len);
  1024. if (newbuf == NULL) {
  1025. __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
  1026. return REDIS_ERR;
  1027. }
  1028. c->obuf = newbuf;
  1029. return REDIS_OK;
  1030. }
  1031. int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
  1032. char *cmd;
  1033. int len;
  1034. len = redisvFormatCommand(&cmd,format,ap);
  1035. if (len == -1) {
  1036. __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
  1037. return REDIS_ERR;
  1038. }
  1039. if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
  1040. free(cmd);
  1041. return REDIS_ERR;
  1042. }
  1043. free(cmd);
  1044. return REDIS_OK;
  1045. }
  1046. int redisAppendCommand(redisContext *c, const char *format, ...) {
  1047. va_list ap;
  1048. int ret;
  1049. va_start(ap,format);
  1050. ret = redisvAppendCommand(c,format,ap);
  1051. va_end(ap);
  1052. return ret;
  1053. }
  1054. int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
  1055. char *cmd;
  1056. int len;
  1057. len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
  1058. if (len == -1) {
  1059. __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
  1060. return REDIS_ERR;
  1061. }
  1062. if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
  1063. free(cmd);
  1064. return REDIS_ERR;
  1065. }
  1066. free(cmd);
  1067. return REDIS_OK;
  1068. }
  1069. /* Helper function for the redisCommand* family of functions.
  1070. *
  1071. * Write a formatted command to the output buffer. If the given context is
  1072. * blocking, immediately read the reply into the "reply" pointer. When the
  1073. * context is non-blocking, the "reply" pointer will not be used and the
  1074. * command is simply appended to the write buffer.
  1075. *
  1076. * Returns the reply when a reply was succesfully retrieved. Returns NULL
  1077. * otherwise. When NULL is returned in a blocking context, the error field
  1078. * in the context will be set.
  1079. */
  1080. static void *__redisBlockForReply(redisContext *c) {
  1081. void *reply;
  1082. if (c->flags & REDIS_BLOCK) {
  1083. if (redisGetReply(c,&reply) != REDIS_OK)
  1084. return NULL;
  1085. return reply;
  1086. }
  1087. return NULL;
  1088. }
  1089. void *redisvCommand(redisContext *c, const char *format, va_list ap) {
  1090. if (redisvAppendCommand(c,format,ap) != REDIS_OK)
  1091. return NULL;
  1092. return __redisBlockForReply(c);
  1093. }
  1094. void *redisCommand(redisContext *c, const char *format, ...) {
  1095. va_list ap;
  1096. void *reply = NULL;
  1097. va_start(ap,format);
  1098. reply = redisvCommand(c,format,ap);
  1099. va_end(ap);
  1100. return reply;
  1101. }
  1102. void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
  1103. if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK)
  1104. return NULL;
  1105. return __redisBlockForReply(c);
  1106. }