TT#39171 avpops: add avp_subst() pvar as subst

* avp_subst(dst, subst_rx)
      - "subst_rx" now supports pvars
        in addition to the static string
      e.g.:
        - avp_subst("$avp(s:dst)", "$avp(s:my_subst)");
        - avp_subst("$avp(s:dst)", "$(rU{uri.param,my_subst})");
      - inline mixed pvars are not supported
      - static subst values are precomplied during the module init
        (as it was before)
      - dynamic pvar subst regex is evaluated and compiled on
        each avp_subst() call
      - optimise internal param handling for static subst values,
        they are stored as (fparam_t*)->type==FPARAM_SUBST

Change-Id: Iea7a91ba87b892edd6fa405aa7cc285d69d9caa9
changes/07/22207/4
Kirill Solomko 8 years ago
parent 0cec8e95a4
commit 3d847c6990

@ -40,3 +40,4 @@ upstream/0001-tm-free-new-cell-in-case-of-error.patch
upstream/0002-tm-force-free-cell-if-transaction-is-unlinkled.patch
upstream/0003-tm-backup-and-restore-T-and-T_branch-in-t_continue.patch
sipwise/extend_stats.patch
sipwise/avpops_avp_subst_pvar.patch

@ -0,0 +1,115 @@
--- a/src/modules/avpops/avpops.c
+++ b/src/modules/avpops/avpops.c
@@ -67,6 +67,7 @@
static int fixup_check_avp(void** param, int param_no);
static int fixup_op_avp(void** param, int param_no);
static int fixup_subst(void** param, int param_no);
+static int fixup_free_subst(void** param, int param_no);
static int fixup_is_avp_set(void** param, int param_no);
static int w_print_avps(struct sip_msg* msg, char* foo, char *bar);
@@ -80,7 +81,7 @@
static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param);
static int w_check_avps(struct sip_msg* msg, char* param, char *check);
static int w_op_avps(struct sip_msg* msg, char* param, char *op);
-static int w_subst(struct sip_msg* msg, char* src, char *subst);
+static int w_subst(struct sip_msg* msg, char* src, char *subst_param);
static int w_is_avp_set(struct sip_msg* msg, char* param, char *foo);
/*! \brief
@@ -109,7 +110,7 @@
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
{"avp_op", (cmd_function)w_op_avps, 2, fixup_op_avp, 0,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
- {"avp_subst", (cmd_function)w_subst, 2, fixup_subst, 0,
+ {"avp_subst", (cmd_function)w_subst, 2, fixup_subst, fixup_free_subst,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
{"is_avp_set", (cmd_function)w_is_avp_set, 1, fixup_is_avp_set, 0,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
@@ -712,8 +713,6 @@
static int fixup_subst(void** param, int param_no)
{
- struct subst_expr* se;
- str subst;
struct fis_param *ap;
struct fis_param **av;
char *s;
@@ -826,23 +825,26 @@
}
*param=(void*)av;
} else if (param_no==2) {
- LM_DBG("%s fixing %s\n", exports.name, (char*)(*param));
- subst.s=*param;
- subst.len=strlen(*param);
- se=subst_parser(&subst);
- if (se==0){
- LM_ERR("%s: bad subst re %s\n",exports.name, (char*)*param);
- return E_BAD_RE;
- }
- /* don't free string -- needed for specifiers */
- /* pkg_free(*param); */
- /* replace it with the compiled subst. re */
- *param=se;
+ if (strncmp((char*)*param, "/", 1) == 0) // static subst string
+ {
+ LM_DBG("%s static subst string: %s\n", exports.name, (char*)*param);
+ return fix_param(FPARAM_SUBST, param);
+ }
+ LM_DBG("%s dynamic avp subst: %s\n", exports.name, (char*)*param);
+ return fixup_var_str_2(param, param_no);
}
return 0;
}
+static int fixup_free_subst(void** param, int param_no)
+{
+ if (param_no==2)
+ fparam_free_restore(param);
+
+ return 0;
+}
+
static int fixup_op_avp(void** param, int param_no)
{
struct fis_param *ap;
@@ -1051,9 +1053,36 @@
(struct fis_param*)op);
}
-static int w_subst(struct sip_msg* msg, char* src, char *subst)
+static int w_subst(struct sip_msg* msg, char* src, char *subst_param)
{
- return ops_subst(msg, (struct fis_param**)src, (struct subst_expr*)subst);
+ str subst;
+ struct subst_expr* se;
+ fparam_t *fp;
+
+ fp = (fparam_t*)subst_param;
+
+ if (fp->type == FPARAM_SUBST) // already precompiled subst
+ {
+ se = fp->v.subst;
+ return ops_subst(msg, (struct fis_param**)src, se);
+ }
+
+ if (get_str_fparam(&subst, msg, fp) != 0)
+ {
+ LM_ERR("error fetching subst re");
+ return -1;
+ }
+
+ LM_DBG("%s preparing %s\n", exports.name, subst.s);
+
+ se=subst_parser(&subst);
+ if (se==0)
+ {
+ LM_ERR("%s: bad subst re %s\n", exports.name, subst.s);
+ return E_BAD_RE;
+ }
+
+ return ops_subst(msg, (struct fis_param**)src, se);
}
static int w_is_avp_set(struct sip_msg* msg, char* param, char *op)
Loading…
Cancel
Save