示例#1
0
文件: hiredis.c 项目: ambakshi/redis
/* Use this function to handle a read event on the descriptor. It will try
 * and read some bytes from the socket and feed them to the reply parser.
 *
 * After this function is called, you may use redisContextReadReply to
 * see if there is a reply available. */
int redisBufferRead(redisContext *c) {
    char buf[2048];
#ifdef _WIN32
    int nread = recv((SOCKET)c->fd,buf,sizeof(buf),0);
    if (nread == -1) {
        errno = WSAGetLastError();
        if ((errno == ENOENT) || (errno == WSAEWOULDBLOCK))
            errno = EAGAIN;
    }
#else
    int nread = read(c->fd,buf,sizeof(buf));
#endif
    if (nread == -1) {
        if (errno == EAGAIN /*&& !(c->flags & REDIS_BLOCK)*/) {
            /* Try again later */
        } else {
            __redisSetError(c,REDIS_ERR_IO,NULL);
            return REDIS_ERR;
        }
    } else if (nread == 0) {
        __redisSetError(c,REDIS_ERR_EOF,
            sdsnew("Server closed the connection"));
        return REDIS_ERR;
    } else {
        __redisCreateReplyReader(c);
        redisReplyReaderFeed(c->reader,buf,nread);
    }
    return REDIS_OK;
}
示例#2
0
/* Use this function to handle a read event on the descriptor. It will try
 * and read some bytes from the socket and feed them to the reply parser.
 *
 * After this function is called, you may use redisContextReadReply to
 * see if there is a reply available. */
int redisBufferRead(redisContext *c) {
    char buf[2048];
    int nread = read(c->fd,buf,sizeof(buf));
    if (nread == -1) {
        if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
            /* Try again later */
        } else {
            __redisSetError(c,REDIS_ERR_IO,NULL);
            return REDIS_ERR;
        }
    } else if (nread == 0) {
        __redisSetError(c,REDIS_ERR_EOF,
            sdsnew("Server closed the connection"));
        return REDIS_ERR;
    } else {
        __redisCreateReplyReader(c);
        redisReplyReaderFeed(c->reader,buf,nread);
    }
    return REDIS_OK;
}
示例#3
0
static void test_reply_reader(void) {
    void *reader;
    void *reply;
    char *err;
    int ret;

    test("Error handling in reply parser: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderFeed(reader,(char*)"@foo\r\n",6);
    ret = redisReplyReaderGetReply(reader,NULL);
    err = redisReplyReaderGetError(reader);
    test_cond(ret == REDIS_ERR &&
              strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0);
    redisReplyReaderFree(reader);

    /* when the reply already contains multiple items, they must be free'd
     * on an error. valgrind will bark when this doesn't happen. */
    test("Memory cleanup in reply parser: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderFeed(reader,(char*)"*2\r\n",4);
    redisReplyReaderFeed(reader,(char*)"$5\r\nhello\r\n",11);
    redisReplyReaderFeed(reader,(char*)"@foo\r\n",6);
    ret = redisReplyReaderGetReply(reader,NULL);
    err = redisReplyReaderGetError(reader);
    test_cond(ret == REDIS_ERR &&
              strcasecmp(err,"Protocol error, got \"@\" as reply type byte") == 0);
    redisReplyReaderFree(reader);

    test("Set error on nested multi bulks with depth > 1: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
    redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
    redisReplyReaderFeed(reader,(char*)"*1\r\n",4);
    ret = redisReplyReaderGetReply(reader,NULL);
    err = redisReplyReaderGetError(reader);
    test_cond(ret == REDIS_ERR &&
              strncasecmp(err,"No support for",14) == 0);
    redisReplyReaderFree(reader);

    test("Works with NULL functions for reply: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderSetReplyObjectFunctions(reader,NULL);
    redisReplyReaderFeed(reader,(char*)"+OK\r\n",5);
    ret = redisReplyReaderGetReply(reader,&reply);
    test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
    redisReplyReaderFree(reader);

    test("Works when a single newline (\\r\\n) covers two calls to feed: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderSetReplyObjectFunctions(reader,NULL);
    redisReplyReaderFeed(reader,(char*)"+OK\r",4);
    ret = redisReplyReaderGetReply(reader,&reply);
    assert(ret == REDIS_OK && reply == NULL);
    redisReplyReaderFeed(reader,(char*)"\n",1);
    ret = redisReplyReaderGetReply(reader,&reply);
    test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
    redisReplyReaderFree(reader);

    test("Properly reset state after protocol error: ");
    reader = redisReplyReaderCreate();
    redisReplyReaderSetReplyObjectFunctions(reader,NULL);
    redisReplyReaderFeed(reader,(char*)"x",1);
    ret = redisReplyReaderGetReply(reader,&reply);
    assert(ret == REDIS_ERR);
    ret = redisReplyReaderGetReply(reader,&reply);
    test_cond(ret == REDIS_OK && reply == NULL)
}