diff --git a/src/modules/posops/doc/posops_admin.xml b/src/modules/posops/doc/posops_admin.xml index 6869e7f6bc4..9e532d7bf35 100644 --- a/src/modules/posops/doc/posops_admin.xml +++ b/src/modules/posops/doc/posops_admin.xml @@ -131,6 +131,82 @@ pos_insert("100", "kamailio-$si"); ... pos_insert("100", "10"); +... + + + +
+ + <function moreinfo="none">pos_headers_start()</function> + + + Return the position in the message buffer where headers start. + + + This function can be used from ANY_ROUTE. + + + <function>pos_headers_start()</function> usage + +... +$var(pos) = pos_headers_start(); +... + + +
+
+ + <function moreinfo="none">pos_headers_end()</function> + + + Return the position in the message buffer where headers end. + + + This function can be used from ANY_ROUTE. + + + <function>pos_headers_end()</function> usage + +... +$var(pos) = pos_headers_end(); +... + + +
+
+ + <function moreinfo="none">pos_body_start()</function> + + + Return the position in the message buffer where body starts. + + + This function can be used from ANY_ROUTE. + + + <function>pos_body_start()</function> usage + +... +$var(pos) = pos_body_start(); +... + + +
+
+ + <function moreinfo="none">pos_body_end()</function> + + + Return the position in the message buffer where body ends. + + + This function can be used from ANY_ROUTE. + + + <function>pos_body_end()</function> usage + +... +$var(pos) = pos_body_end(); ... diff --git a/src/modules/posops/posops_mod.c b/src/modules/posops/posops_mod.c index 834846a3f74..dbcd45ce423 100644 --- a/src/modules/posops/posops_mod.c +++ b/src/modules/posops/posops_mod.c @@ -41,12 +41,21 @@ static void mod_destroy(void); static int w_posops_pos_append(sip_msg_t* msg, char* p1idx, char* p2val); static int w_posops_pos_insert(sip_msg_t* msg, char* p1idx, char* p2val); static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len); +static int w_posops_pos_headers_start(sip_msg_t* msg, char* p1, char* p2); +static int w_posops_pos_headers_end(sip_msg_t* msg, char* p1, char* p2); +static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2); +static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2); typedef struct posops_data { int ret; int idx; } pospos_data_t; +/** + * + */ +static pospos_data_t _pospos_data = {0}; + /* clang-format off */ static cmd_export_t cmds[]={ {"pos_append", (cmd_function)w_posops_pos_append, 2, fixup_igp_spve, @@ -55,6 +64,14 @@ static cmd_export_t cmds[]={ fixup_free_igp_spve, ANY_ROUTE}, {"pos_rm", (cmd_function)w_posops_pos_rm, 2, fixup_igp_igp, fixup_free_igp_igp, ANY_ROUTE}, + {"pos_headers_start", (cmd_function)w_posops_pos_headers_start, 0, 0, + 0, ANY_ROUTE}, + {"pos_headers_end", (cmd_function)w_posops_pos_headers_end, 0, 0, + 0, ANY_ROUTE}, + {"pos_body_start", (cmd_function)w_posops_pos_body_start, 0, 0, + 0, ANY_ROUTE}, + {"pos_body_end", (cmd_function)w_posops_pos_body_end, 0, 0, + 0, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -270,6 +287,126 @@ static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len) return ki_posops_pos_rm(msg, idx, len); } +/** + * + */ +static int ki_posops_pos_headers_start(sip_msg_t* msg) +{ + int ret = 0; + + memset(&_pospos_data, 0, sizeof(pospos_data_t)); + if (parse_headers(msg, HDR_EOH_F, 0) == -1) { + LM_ERR("failed to parse headers\n"); + return -1; + } + + ret = msg->first_line.len; + _pospos_data.idx = ret; + + return (ret==0)?-255:ret; +} + +/** + * + */ +static int w_posops_pos_headers_start(sip_msg_t* msg, char* p1, char* p2) +{ + return ki_posops_pos_headers_start(msg); +} + +/** + * + */ +static int ki_posops_pos_headers_end(sip_msg_t* msg) +{ + int ret = 0; + + memset(&_pospos_data, 0, sizeof(pospos_data_t)); + if (parse_headers(msg, HDR_EOH_F, 0) == -1) { + LM_ERR("failed to parse headers\n"); + return -1; + } + + ret = msg->unparsed - msg->buf; + _pospos_data.idx = ret; + + return (ret==0)?-255:ret; +} + +/** + * + */ +static int w_posops_pos_headers_end(sip_msg_t* msg, char* p1, char* p2) +{ + return ki_posops_pos_headers_end(msg); +} + +/** + * + */ +static int ki_posops_pos_body_start(sip_msg_t* msg) +{ + int ret = 0; + char *body = 0; + + memset(&_pospos_data, 0, sizeof(pospos_data_t)); + if (parse_headers(msg, HDR_EOH_F, 0) == -1) { + LM_ERR("failed to parse headers\n"); + return -1; + } + + body = get_body(msg); + if(body == NULL) { + LM_DBG("no body\n"); + return -1; + } + ret = body - msg->buf; + _pospos_data.idx = ret; + + return (ret==0)?-255:ret; +} + +/** + * + */ +static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2) +{ + return ki_posops_pos_body_start(msg); +} + +/** + * + */ +static int ki_posops_pos_body_end(sip_msg_t* msg) +{ + int ret = 0; + + memset(&_pospos_data, 0, sizeof(pospos_data_t)); + if (parse_headers(msg, HDR_EOH_F, 0) == -1) { + LM_ERR("failed to parse headers\n"); + return -1; + } + + if(get_body(msg) == NULL) { + LM_DBG("no body\n"); + return -1; + } + + ret = msg->len; + _pospos_data.idx = ret; + + return (ret==0)?-255:ret; +} + +/** + * + */ +static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2) +{ + return ki_posops_pos_body_end(msg); +} + + /** * */ @@ -290,6 +427,26 @@ static sr_kemi_t sr_kemi_posops_exports[] = { { SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("posops"), str_init("pos_headers_start"), + SR_KEMIP_INT, ki_posops_pos_headers_start, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("posops"), str_init("pos_headers_end"), + SR_KEMIP_INT, ki_posops_pos_headers_end, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("posops"), str_init("pos_body_start"), + SR_KEMIP_INT, ki_posops_pos_body_start, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("posops"), str_init("pos_body_end"), + SR_KEMIP_INT, ki_posops_pos_body_end, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } };