diff options
author | dormando <dormando@rydia.net> | 2022-07-29 18:38:15 -0700 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2022-08-03 11:53:29 -0700 |
commit | 2389436317fe9d74d390d0adfe4a2679c693375e (patch) | |
tree | bd49936324871903bf3c2f2a10014e174638f41c | |
parent | 4f07a597bbd0367d6458ed4c65f47ec9ca3910cd (diff) | |
download | memcached-2389436317fe9d74d390d0adfe4a2679c693375e.tar.gz |
proxy: mcp.request improvements
- errors if a string value is missing the "\r\n" terminator
- properly uses a value from a response object
- allows passing in a request object for the value as well
- also adds r:vlen() for recovering the value length of a response
think this still needs r:flags() or similar?
-rw-r--r-- | proxy_lua.c | 18 | ||||
-rw-r--r-- | proxy_request.c | 20 | ||||
-rw-r--r-- | t/startfile.lua | 7 |
3 files changed, 40 insertions, 5 deletions
diff --git a/proxy_lua.c b/proxy_lua.c index 5f5707c..383f747 100644 --- a/proxy_lua.c +++ b/proxy_lua.c @@ -32,6 +32,23 @@ static int mcplib_response_hit(lua_State *L) { return 1; } +// Caller needs to discern if a vlen is 0 because of a failed response or an +// OK response that was actually zero. So we always return an integer value +// here. +static int mcplib_response_vlen(lua_State *L) { + mcp_resp_t *r = luaL_checkudata(L, -1, "mcp.response"); + + // We do remove the "\r\n" from the value length, so if you're actually + // processing the value nothing breaks. + if (r->resp.vlen >= 2) { + lua_pushinteger(L, r->resp.vlen-2); + } else { + lua_pushinteger(L, 0); + } + + return 1; +} + static int mcplib_response_gc(lua_State *L) { mcp_resp_t *r = luaL_checkudata(L, -1, "mcp.response"); @@ -773,6 +790,7 @@ int proxy_register_libs(LIBEVENT_THREAD *t, void *ctx) { const struct luaL_Reg mcplib_response_m[] = { {"ok", mcplib_response_ok}, {"hit", mcplib_response_hit}, + {"vlen", mcplib_response_vlen}, {"__gc", mcplib_response_gc}, {NULL, NULL} }; diff --git a/proxy_request.c b/proxy_request.c index 259ec90..9918499 100644 --- a/proxy_request.c +++ b/proxy_request.c @@ -529,13 +529,23 @@ int mcplib_request(lua_State *L) { int type = lua_type(L, 2); if (type == LUA_TSTRING) { val = luaL_optlstring(L, 2, NULL, &vlen); + if (vlen < 2 || memcmp(val+vlen-2, "\r\n", 2) != 0) { + proxy_lua_error(L, "value passed to mcp.request must end with \\r\\n"); + } } else if (type == LUA_TUSERDATA) { - mcp_resp_t *r = luaL_checkudata(L, 2, "mcp.response"); - if (r->buf) { - val = r->buf; - vlen = r->blen; + // vlen for requests and responses include the "\r\n" already. + mcp_resp_t *r = luaL_testudata(L, 2, "mcp.response"); + if (r != NULL) { + if (r->resp.value) { + val = r->resp.value; + vlen = r->resp.vlen_read; // paranoia, so we can't overread into memory. + } } else { - // TODO (v2): other response modes unhandled. + mcp_request_t *rq = luaL_testudata(L, 2, "mcp.request"); + if (rq->pr.vbuf) { + val = rq->pr.vbuf; + vlen = rq->pr.vlen; + } } } diff --git a/t/startfile.lua b/t/startfile.lua index c8e3806..c204d49 100644 --- a/t/startfile.lua +++ b/t/startfile.lua @@ -151,6 +151,10 @@ function failover_factory(zones, local_zone) end return restable[1], "failover_backup_miss" end + -- example of making a new set request on the side. + -- local nr = mcp.request("set /foo/asdf 0 0 " .. res:vlen() .. "\r\n", res) + -- local nr = mcp.request("set /foo/asdf 0 0 2\r\n", "mo\r\n") + -- near_zone(nr) return res, "failover_hit" -- send result back to client end end @@ -172,6 +176,9 @@ function setinvalidate_factory(zones, local_zone) if res:ok() == true then -- create a new delete request local dr = new_req("delete /testing/" .. r:key() .. "\r\n") + -- example of new request from existing request + -- note this isn't trimming the key so it'll make a weird one. + -- local dr = new_req("set /bar/" .. r:key() .. " 0 0 " .. r:token(5) .. "\r\n", r) for _, zone in pairs(far_zones) do -- NOTE: can check/do things on the specific response here. zone(dr) |