Browse code

pv: new transformations {s.after,char} and {s.before,char}

Daniel-Constantin Mierla authored on 14/02/2021 08:40:34
Showing 2 changed files
... ...
@@ -1316,6 +1316,94 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1316 1316
 			val->rs.s = int2str(j, &val->rs.len);
1317 1317
 			break;
1318 1318
 
1319
+		case TR_S_BEFORE:
1320
+			if(tp==NULL)
1321
+			{
1322
+				LM_ERR("invalid parameters (cfg line: %d)\n",
1323
+						get_cfg_crt_line());
1324
+				return -1;
1325
+			}
1326
+			if(!(val->flags&PV_VAL_STR)) {
1327
+				val->rs.s = int2str(val->ri, &val->rs.len);
1328
+			}
1329
+			if(val->rs.len>TR_BUFFER_SIZE-2) {
1330
+				LM_ERR("value too large: %d\n", val->rs.len);
1331
+				return -1;
1332
+			}
1333
+			if(tp->type==TR_PARAM_STRING)
1334
+			{
1335
+				st = tp->v.s;
1336
+			} else {
1337
+				if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1338
+						|| (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1339
+				{
1340
+					LM_ERR("cannot get parameter value (cfg line: %d)\n",
1341
+							get_cfg_crt_line());
1342
+					return -1;
1343
+				}
1344
+				st = v.rs;
1345
+			}
1346
+			for(i=0; i<val->rs.len; i++) {
1347
+				if(val->rs.s[i]==st.s[0]) {
1348
+					break;
1349
+				}
1350
+			}
1351
+			if(i==0) {
1352
+				_tr_buffer[0] = '\0';
1353
+				val->rs.len = 0;
1354
+			} else {
1355
+				memcpy(_tr_buffer, val->rs.s, i);
1356
+				val->rs.len = i;
1357
+			}
1358
+			val->flags = PV_VAL_STR;
1359
+			val->rs.s = _tr_buffer;
1360
+			val->rs.s[val->rs.len] = '\0';
1361
+			break;
1362
+
1363
+		case TR_S_AFTER:
1364
+			if(tp==NULL)
1365
+			{
1366
+				LM_ERR("invalid parameters (cfg line: %d)\n",
1367
+						get_cfg_crt_line());
1368
+				return -1;
1369
+			}
1370
+			if(!(val->flags&PV_VAL_STR)) {
1371
+				val->rs.s = int2str(val->ri, &val->rs.len);
1372
+			}
1373
+			if(val->rs.len>TR_BUFFER_SIZE-2) {
1374
+				LM_ERR("value too large: %d\n", val->rs.len);
1375
+				return -1;
1376
+			}
1377
+			if(tp->type==TR_PARAM_STRING)
1378
+			{
1379
+				st = tp->v.s;
1380
+			} else {
1381
+				if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
1382
+						|| (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
1383
+				{
1384
+					LM_ERR("cannot get parameter value (cfg line: %d)\n",
1385
+							get_cfg_crt_line());
1386
+					return -1;
1387
+				}
1388
+				st = v.rs;
1389
+			}
1390
+			for(i=0; i<val->rs.len; i++) {
1391
+				if(val->rs.s[i]==st.s[0]) {
1392
+					break;
1393
+				}
1394
+			}
1395
+			if(i>=val->rs.len-1) {
1396
+				_tr_buffer[0] = '\0';
1397
+				val->rs.len = 0;
1398
+			} else {
1399
+				memcpy(_tr_buffer, val->rs.s+i+1, val->rs.len-i-1);
1400
+				val->rs.len = val->rs.len-i-1;
1401
+			}
1402
+			val->flags = PV_VAL_STR;
1403
+			val->rs.s = _tr_buffer;
1404
+			val->rs.s[val->rs.len] = '\0';
1405
+			break;
1406
+
1319 1407
 		default:
1320 1408
 			LM_ERR("unknown subtype %d (cfg line: %d)\n",
1321 1409
 					subtype, get_cfg_crt_line());
... ...
@@ -2786,6 +2874,46 @@ char* tr_parse_string(str* in, trans_t *t)
2786 2874
 			goto error;
2787 2875
 		}
2788 2876
 		goto done;
2877
+	} else if(name.len==6 && strncasecmp(name.s, "before", 6)==0) {
2878
+		t->subtype = TR_S_BEFORE;
2879
+		if(*p!=TR_PARAM_MARKER)
2880
+		{
2881
+			LM_ERR("invalid before transformation: %.*s!\n",
2882
+					in->len, in->s);
2883
+			goto error;
2884
+		}
2885
+		p++;
2886
+		_tr_parse_sparamx(p, p0, tp, spec, ps, in, s, 1);
2887
+		t->params = tp;
2888
+		tp = 0;
2889
+		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
2890
+		if(*p!=TR_RBRACKET)
2891
+		{
2892
+			LM_ERR("invalid before transformation: %.*s!!\n",
2893
+					in->len, in->s);
2894
+			goto error;
2895
+		}
2896
+		goto done;
2897
+	} else if(name.len==5 && strncasecmp(name.s, "after", 5)==0) {
2898
+		t->subtype = TR_S_AFTER;
2899
+		if(*p!=TR_PARAM_MARKER)
2900
+		{
2901
+			LM_ERR("invalid after transformation: %.*s!\n",
2902
+					in->len, in->s);
2903
+			goto error;
2904
+		}
2905
+		p++;
2906
+		_tr_parse_sparamx(p, p0, tp, spec, ps, in, s, 1);
2907
+		t->params = tp;
2908
+		tp = 0;
2909
+		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
2910
+		if(*p!=TR_RBRACKET)
2911
+		{
2912
+			LM_ERR("invalid after transformation: %.*s!!\n",
2913
+					in->len, in->s);
2914
+			goto error;
2915
+		}
2916
+		goto done;
2789 2917
 	}
2790 2918
 
2791 2919
 	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
... ...
@@ -44,7 +44,8 @@ enum _tr_s_subtype {
44 44
 	TR_S_ENCODEBASE58, TR_S_DECODEBASE58, TR_S_COREHASH, TR_S_UNQUOTE,
45 45
 	TR_S_UNBRACKET, TR_S_COUNT, TR_S_ENCODEBASE64T, TR_S_DECODEBASE64T,
46 46
 	TR_S_ENCODEBASE64URL, TR_S_DECODEBASE64URL,
47
-	TR_S_ENCODEBASE64URLT, TR_S_DECODEBASE64URLT, TR_S_RMWS
47
+	TR_S_ENCODEBASE64URLT, TR_S_DECODEBASE64URLT, TR_S_RMWS, TR_S_BEFORE,
48
+	TR_S_AFTER
48 49
 };
49 50
 enum _tr_uri_subtype {
50 51
 	TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,