]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: lua: automatically converts strings in proxy, tables, server and ip
authorThierry FOURNIER <tfournier@haproxy.com>
Thu, 12 Mar 2015 17:28:50 +0000 (18:28 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 13 Mar 2015 13:10:27 +0000 (14:10 +0100)
This patch adds automatic solve of proxy, table and server names.
If ips or masks are required, they try to convert from the input
string.

src/hlua.c

index d59a462d5d948ce8d85d3671059d9b6e96dc1dbc..d1086c724195a624de4fd7db6301d83dbb4bca82 100644 (file)
@@ -116,7 +116,8 @@ static unsigned int hlua_nb_instruction = 10000;
  */
 static int hlua_arg2lua(lua_State *L, const struct arg *arg);
 static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
-__LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, unsigned int mask);
+__LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
+                                     unsigned int mask, struct proxy *p);
 static int hlua_smp2lua(lua_State *L, struct sample *smp);
 static int hlua_smp2lua_str(lua_State *L, struct sample *smp);
 static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
@@ -508,10 +509,13 @@ static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
  * is in accord with the expected argp defined by the "mask". The fucntion
  * returns true or false. It can be adjust the types if there compatibles.
  */
-__LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, unsigned int mask)
+__LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
+                              unsigned int mask, struct proxy *p)
 {
        int min_arg;
        int idx;
+       struct proxy *px;
+       char *sname, *pname;
 
        idx = 0;
        min_arg = ARGM(mask);
@@ -542,14 +546,117 @@ __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, unsigne
                        return 0;
                }
 
-               /* Compatibility mask. */
-               switch (argp[idx].type) {
+               /* Convert some argument types. */
+               switch (mask & ARGT_MASK) {
                case ARGT_SINT:
-                       switch (mask & ARGT_MASK) {
-                       case ARGT_UINT: argp[idx].type = mask & ARGT_MASK; break;
-                       case ARGT_TIME: argp[idx].type = mask & ARGT_MASK; break;
-                       case ARGT_SIZE: argp[idx].type = mask & ARGT_MASK; break;
+                       if (argp[idx].type != ARGT_SINT)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
+                       argp[idx].type = ARGT_SINT;
+                       break;
+
+               case ARGT_UINT:
+                       if (argp[idx].type != ARGT_SINT)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
+                       argp[idx].type = ARGT_SINT;
+                       break;
+
+               case ARGT_TIME:
+                       if (argp[idx].type != ARGT_SINT)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
+                       argp[idx].type = ARGT_SINT;
+                       break;
+
+               case ARGT_SIZE:
+                       if (argp[idx].type != ARGT_SINT)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
+                       argp[idx].type = ARGT_SINT;
+                       break;
+
+               case ARGT_FE:
+                       if (argp[idx].type != ARGT_STR)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       argp[idx].data.prx = findproxy(trash.str, PR_CAP_FE);
+                       if (!argp[idx].data.prx)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "frontend doesn't exist"));
+                       argp[idx].type = ARGT_FE;
+                       break;
+
+               case ARGT_BE:
+                       if (argp[idx].type != ARGT_STR)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       argp[idx].data.prx = findproxy(trash.str, PR_CAP_BE);
+                       if (!argp[idx].data.prx)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
+                       argp[idx].type = ARGT_BE;
+                       break;
+
+               case ARGT_TAB:
+                       if (argp[idx].type != ARGT_STR)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       argp[idx].data.prx = find_stktable(trash.str);
+                       if (!argp[idx].data.prx)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "table doesn't exist"));
+                       argp[idx].type = ARGT_TAB;
+                       break;
+
+               case ARGT_SRV:
+                       if (argp[idx].type != ARGT_STR)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       sname = strrchr(trash.str, '/');
+                       if (sname) {
+                               *sname++ = '\0';
+                               pname = trash.str;
+                               px = findproxy(pname, PR_CAP_BE);
+                               if (!px)
+                                       WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
+                       }
+                       else {
+                               sname = trash.str;
+                               px = p;
                        }
+                       argp[idx].data.srv = findserver(px, sname);
+                       if (!argp[idx].data.srv)
+                               WILL_LJMP(luaL_argerror(L, first + idx, "server doesn't exist"));
+                       argp[idx].type = ARGT_SRV;
+                       break;
+
+               case ARGT_IPV4:
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       if (inet_pton(AF_INET, trash.str, &argp[idx].data.ipv4))
+                               WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 address"));
+                       argp[idx].type = ARGT_IPV4;
+                       break;
+
+               case ARGT_MSK4:
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       if (!str2mask(trash.str, &argp[idx].data.ipv4))
+                               WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 mask"));
+                       argp[idx].type = ARGT_MSK4;
+                       break;
+
+               case ARGT_IPV6:
+                       memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
+                       trash.str[argp[idx].data.str.len] = 0;
+                       if (inet_pton(AF_INET6, trash.str, &argp[idx].data.ipv6))
+                               WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv6 address"));
+                       argp[idx].type = ARGT_IPV6;
+                       break;
+
+               case ARGT_MSK6:
+               case ARGT_MAP:
+               case ARGT_REG:
+               case ARGT_USR:
+                       WILL_LJMP(luaL_argerror(L, first + idx, "type not yet supported"));
                        break;
                }