Browse code

pv: added {s.rafter,x} and {s.rbefore,x}

- similar to {s.after,x} and {s.before,x}, but searches from end of the
value

Daniel-Constantin Mierla authored on 25/06/2021 07:51:10
Showing 2 changed files
... ...
@@ -1340,6 +1340,7 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1340 1340
 			break;
1341 1341
 
1342 1342
 		case TR_S_BEFORE:
1343
+		case TR_S_RBEFORE:
1343 1344
 			if(tp==NULL)
1344 1345
 			{
1345 1346
 				LM_ERR("invalid parameters (cfg line: %d)\n",
... ...
@@ -1366,11 +1367,20 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1366 1367
 				}
1367 1368
 				st = v.rs;
1368 1369
 			}
1369
-			for(i=0; i<val->rs.len; i++) {
1370
-				if(val->rs.s[i]==st.s[0]) {
1371
-					break;
1370
+			if(subtype==TR_S_BEFORE) {
1371
+				for(i=0; i<val->rs.len; i++) {
1372
+					if(val->rs.s[i]==st.s[0]) {
1373
+						break;
1374
+					}
1375
+				}
1376
+			} else {
1377
+				for(i=val->rs.len-1; i>=0; i++) {
1378
+					if(val->rs.s[i]==st.s[0]) {
1379
+						break;
1380
+					}
1372 1381
 				}
1373 1382
 			}
1383
+
1374 1384
 			if(i==0) {
1375 1385
 				_tr_buffer[0] = '\0';
1376 1386
 				val->rs.len = 0;
... ...
@@ -1384,6 +1394,7 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1384 1394
 			break;
1385 1395
 
1386 1396
 		case TR_S_AFTER:
1397
+		case TR_S_RAFTER:
1387 1398
 			if(tp==NULL)
1388 1399
 			{
1389 1400
 				LM_ERR("invalid parameters (cfg line: %d)\n",
... ...
@@ -1410,9 +1421,17 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
1410 1421
 				}
1411 1422
 				st = v.rs;
1412 1423
 			}
1413
-			for(i=0; i<val->rs.len; i++) {
1414
-				if(val->rs.s[i]==st.s[0]) {
1415
-					break;
1424
+			if(subtype==TR_S_AFTER) {
1425
+				for(i=0; i<val->rs.len; i++) {
1426
+					if(val->rs.s[i]==st.s[0]) {
1427
+						break;
1428
+					}
1429
+				}
1430
+			} else {
1431
+				for(i=val->rs.len-1; i>=0; i++) {
1432
+					if(val->rs.s[i]==st.s[0]) {
1433
+						break;
1434
+					}
1416 1435
 				}
1417 1436
 			}
1418 1437
 			if(i>=val->rs.len-1) {
... ...
@@ -3012,6 +3031,46 @@ char* tr_parse_string(str* in, trans_t *t)
3012 3031
 			goto error;
3013 3032
 		}
3014 3033
 		goto done;
3034
+	} else if(name.len==7 && strncasecmp(name.s, "rbefore", 7)==0) {
3035
+		t->subtype = TR_S_RBEFORE;
3036
+		if(*p!=TR_PARAM_MARKER)
3037
+		{
3038
+			LM_ERR("invalid rbefore transformation: %.*s!\n",
3039
+					in->len, in->s);
3040
+			goto error;
3041
+		}
3042
+		p++;
3043
+		_tr_parse_sparamx(p, p0, tp, spec, ps, in, s, 1);
3044
+		t->params = tp;
3045
+		tp = 0;
3046
+		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3047
+		if(*p!=TR_RBRACKET)
3048
+		{
3049
+			LM_ERR("invalid rbefore transformation: %.*s!!\n",
3050
+					in->len, in->s);
3051
+			goto error;
3052
+		}
3053
+		goto done;
3054
+	} else if(name.len==6 && strncasecmp(name.s, "rafter", 6)==0) {
3055
+		t->subtype = TR_S_RAFTER;
3056
+		if(*p!=TR_PARAM_MARKER)
3057
+		{
3058
+			LM_ERR("invalid rafter transformation: %.*s!\n",
3059
+					in->len, in->s);
3060
+			goto error;
3061
+		}
3062
+		p++;
3063
+		_tr_parse_sparamx(p, p0, tp, spec, ps, in, s, 1);
3064
+		t->params = tp;
3065
+		tp = 0;
3066
+		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
3067
+		if(*p!=TR_RBRACKET)
3068
+		{
3069
+			LM_ERR("invalid rafter transformation: %.*s!!\n",
3070
+					in->len, in->s);
3071
+			goto error;
3072
+		}
3073
+		goto done;
3015 3074
 	}
3016 3075
 
3017 3076
 	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
... ...
@@ -45,7 +45,7 @@ enum _tr_s_subtype {
45 45
 	TR_S_UNBRACKET, TR_S_COUNT, TR_S_ENCODEBASE64T, TR_S_DECODEBASE64T,
46 46
 	TR_S_ENCODEBASE64URL, TR_S_DECODEBASE64URL,
47 47
 	TR_S_ENCODEBASE64URLT, TR_S_DECODEBASE64URLT, TR_S_RMWS, TR_S_BEFORE,
48
-	TR_S_AFTER
48
+	TR_S_AFTER, TR_S_RBEFORE, TR_S_RAFTER
49 49
 };
50 50
 enum _tr_uri_subtype {
51 51
 	TR_URI_NONE=0, TR_URI_USER, TR_URI_HOST, TR_URI_PASSWD, TR_URI_PORT,