Exemple #1
0
void luaCommand(redisClient *c) {
    //printf("LUA: %s\n", c->argv[1]->ptr);
    LuaFlag   = PIPE_NONE_FLAG;
    LuaClient = c;             /* used in func redisLua */
    int s     = luaL_dostring(Lua, c->argv[1]->ptr);
    if (s) {
        const char *x = lua_tostring(Lua, -1);
        lua_pop(Lua, 1);
        addReplySds(c, sdscatprintf(sdsempty(), "-ERR Lua error: %s \r\n", x));
        return;
    }

    int lret = lua_gettop(Lua);
    //printf("LuaFlag: %d lret: %d\n", LuaFlag, lret);
    if (lua_istable(Lua, -1)) {
        const int len = lua_objlen(Lua, -1 );
        addReplySds(c, sdscatprintf(sdsempty(), "*%d\r\n", len));
        for (int i = 1; i <= len; ++i ) {
            lua_pushinteger(Lua, i);
            lua_gettable(Lua, -2);
            char *x = (char *)lua_tostring(Lua, -1);
            robj *r = _createStringObject(x);
            addReplyBulk(c, r);
            decrRefCount(r);
            lua_pop(Lua, 1);
        }
        lua_pop(Lua, 1);
    } else if (LuaFlag == PIPE_EMPTY_SET_FLAG) {
        addReply(c, shared.emptymultibulk);
        lua_pop(Lua, 1); /* pop because Pipe adds "-1" for Multi-NonRelIndxs */
    } else if (!lret) {
        addReply(c, shared.nullbulk);
    } else {
        char *x = (char *)lua_tostring(Lua, -1);
        if (!x) {
            addReply(c, shared.nullbulk);
        } else { 
            /* NOTE: if "client() is called in a lua func and the lua func
                     then returns "+OK" it will 'correctly' returned */
            if (LuaFlag == PIPE_ONE_LINER_FLAG &&
                (*x == '-' || *x == '+' || *x == ':')) {
                addReplySds(c, sdscatprintf(sdsempty(), "%s\r\n", x));
            } else {
                robj *r = _createStringObject(x);
                addReplyBulk(c, r);
                decrRefCount(r);
            }
        }
        lua_pop(Lua, 1);
    }
    lua_gc(Lua, LUA_GCCOLLECT, 0);
}
static void sendStaticFileReply(cli *c) {
    robj *o;
    if ((o = lookupKeyRead(c->db, c->http.file)) == NULL) SEND_404
    else if (o->type != REDIS_STRING)                     SEND_404
    else { //NOTE: STATIC expire in 10 years (HARDCODED)
        listNode *ln;
        bool      dfl = 0;
        listIter *li  = listGetIterator(c->http.req_hdr, AL_START_HEAD);
        while((ln = listNext(li))) { // check for "deflate"
            two_sds *ss = ln->value;
            if (!strncasecmp(ss->a, "Accept-Encoding", 15)) {
                if (DXDB_strcasestr(ss->b, "deflate")) { dfl = 1; break; }
            }
        } listReleaseIterator(li);
        if (dfl) {
            robj *dfile = _createStringObject("DEFLATE/");
            dfile->ptr  = sdscatlen(dfile->ptr, c->http.file->ptr,
                                                sdslen(c->http.file->ptr));
            robj *od;
            if ((od = lookupKeyRead(c->db, dfile)) && od->type == REDIS_STRING){
                o = od;
                addHttpResponseHeader(sdsnew("Content-Encoding"),
                                      sdsnew("deflate"));
            }
        }
        addHttpResponseHeader(sdsnew("Expires"),
                              sdsnew("Wed, 09 Jun 2021 10:18:14 GMT;"));
        SEND_REPLY_FROM_STRING(send_http200_reponse_header(c, sdslen(o->ptr)));
        addReply(c, o);
    }
}
Exemple #3
0
/* This gets called when the function "client)" gets called in Lua */
int luaCall_client(lua_State *L) {
    LuaFlag            = PIPE_NONE_FLAG;
    int           argc = lua_gettop(L);
    const char   *arg1 = lua_tostring(L, 1);
    if (!arg1) {
        return redisLuaArityErr(L, NULL);
    }
    redisCommand *cmd  = lookupCommand((char *)arg1);

    if (!cmd) {
        char buf[64];
        snprintf(buf, 63, "-ERR Unknown command '%s'\r\n", arg1);
        buf[63] = '\0';
        lua_pushstring(L, buf);
        LuaFlag = PIPE_ONE_LINER_FLAG;
        return 1;
    } else if ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity)) {
        return redisLuaArityErr(L, cmd->name);
    }

    if (server.maxmemory && (cmd->flags & REDIS_CMD_DENYOOM) &&
        (zmalloc_used_memory() > server.maxmemory)) {
        LuaFlag = PIPE_ONE_LINER_FLAG;
        lua_pushstring(L,
                 "-ERR command not allowed when used memory > 'maxmemory'\r\n");
        return 1;
    }

    if (server.vm_enabled && server.vm_max_threads > 0 &&
        blockClientOnSwappedKeys(LuaClient, cmd)) return 1;

    long          ok    = 0; /* must come before first GOTO */
    redisClient  *rfc   = rsql_createFakeClient();
    robj        **rargv = zmalloc(sizeof(robj *) * argc);
    for (int i = 0; i < argc; i++) {
        char *arg = (char *)lua_tostring(L, i + 1);
        if (!arg) {
            char *lbuf = "args must be strings";
            luaL_argerror (L, i, lbuf);
            LuaFlag    = PIPE_ONE_LINER_FLAG;
            ok         = 1;
            goto redis_lua_end;
        }
        rargv[i] = _createStringObject(arg);
    }
    rfc->argv = rargv;
    rfc->argc = argc;

    ok = fakeClientPipe(LuaClient, rfc, L, 0, &LuaFlag, luaLine, emptyNoop);

redis_lua_end:
    for (int i = 0; i < argc; i++) decrRefCount(rargv[i]);
    zfree(rargv);
    rsql_freeFakeClient(rfc);
    return (ok > 0) ? 1 : 0;
}
Exemple #4
0
bool replyIfNestedErr(redisClient *c, redisClient *rfc, char *msg) {
    if (!respNotErr(rfc)) {
        listNode *ln   = listFirst(rfc->reply);
        robj     *emsg = ln->value;
        robj     *repl = _createStringObject(msg);
        repl->ptr      = sdscatlen(repl->ptr, emsg->ptr, sdslen(emsg->ptr));
        addReply(c, repl);
        decrRefCount(repl);
        return 0;
    }
    return 1;
}
Exemple #5
0
static bool nonRelIndRespHandler(redisClient *c,
                                 void        *x,
                                 robj        *key,
                                 long        *card,
                                 int          b,   /* variable ignored */
                                 int          n) { /* variable ignored */
    x = 0; b = 0; n = 0; /* compiler warnings */
    if (NriFlag == PIPE_ONE_LINER_FLAG) {
        char *s = key->ptr;
        robj *r = _createStringObject(s + 1); /* +1 skips '+','-',':' */
        decrRefCount(key);
        key     = r;
    }
    addReplyBulk(c, key);
    decrRefCount(key);
    *card = *card + 1;
    CurrCard++;
    return 1;
}
static void sendLuaFuncReply(cli *c, sds file) { //printf("sendLuaFuncReply\n");
    int argc; robj **rargv = NULL;
    if (!sdslen(file) || !strcmp(file, "/")) {
        argc      = 2; //NOTE: rargv[0] is ignored
        rargv     = zmalloc(sizeof(robj *) * argc);
        rargv[1]  = _createStringObject(server.alc.WebServerIndexFunc);
    } else if (c->http.post && c->http.req_clen) {
        int  urgc;
        sds *urgv = sdssplitlen(file, sdslen(file), "/", 1, &urgc);
        sds  pb   = c->http.post_body;
        sds *argv = sdssplitlen(pb, sdslen(pb), "&", 1, &argc);
        rargv     = zmalloc(sizeof(robj *) * (argc + urgc + 1));
        for (int i = 0; i < urgc; i++) {
            rargv[i + 1] = createStringObject(urgv[i], sdslen(urgv[i]));
        }
        for (int i = 0; i < argc; i++) {
            char *x = strchr(argv[i], '=');
            if (!x) continue; x++;
            rargv[i + urgc + 1] = createStringObject(x, strlen(x));
        }
        for (int i = 0; i < urgc; i++) sdsfree(urgv[i]);
        zfree(urgv); zfree(argv);
        argc += (urgc + 1); //NOTE: rargv[0] is ignored
    } else {
        sds *argv = sdssplitlen(file, sdslen(file), "/", 1, &argc);
        rargv     = zmalloc(sizeof(robj *) * (argc + 1));
        for (int i = 0; i < argc; i++) {
            rargv[i + 1] = createStringObject(argv[i], sdslen(argv[i]));
        }
        for (int i = 0; i < argc; i++) sdsfree(argv[i]);
        zfree(argv);
        argc++; //NOTE: rargv[0] is ignored
    }
    if (!luafunc_call(c, argc, rargv)) {
        robj *resp = luaReplyToHTTPReply(server.lua);
        SEND_REPLY_FROM_STRING(send_http_reponse_header(c, sdslen(resp->ptr)));
        if (c->http.get || c->http.post) addReply(c, resp);
        decrRefCount(resp);
    }
    for (int i = 1; i < argc; i++) decrRefCount(rargv[i]);
    zfree(rargv);
    CLEAR_LUA_STACK
}