@@ -309,9 +309,9 @@ mod tests {
309
309
use ast:: function_expr:: { FunctionCallArgExpr , FunctionCallExpr } ;
310
310
use cidr:: { Cidr , IpCidr } ;
311
311
use execution_context:: ExecutionContext ;
312
- use functions:: { Function , FunctionArg , FunctionArgKind , FunctionImpl } ;
312
+ use functions:: { Function , FunctionArg , FunctionArgKind , FunctionImpl , FunctionOptArg } ;
313
313
use lazy_static:: lazy_static;
314
- use rhs_types:: IpRange ;
314
+ use rhs_types:: { Bytes , IpRange } ;
315
315
use std:: net:: IpAddr ;
316
316
317
317
fn echo_function < ' a > ( args : & [ LhsValue < ' a > ] ) -> LhsValue < ' a > {
@@ -330,6 +330,20 @@ mod tests {
330
330
}
331
331
}
332
332
333
+ fn concat_function < ' a , ' r > ( args : & ' r [ LhsValue < ' a > ] ) -> LhsValue < ' a > {
334
+ match ( & args[ 0 ] , & args[ 1 ] ) {
335
+ ( LhsValue :: Bytes ( buf1) , LhsValue :: Bytes ( buf2) ) => {
336
+ let mut vec1 = buf1. to_vec ( ) ;
337
+ vec1. extend_from_slice ( & * buf2) ;
338
+ LhsValue :: Bytes ( vec1. into ( ) )
339
+ }
340
+ _ => panic ! (
341
+ "Invalid types: expected (Bytes, Bytes), got ({:?}, {:?})" ,
342
+ args[ 0 ] , args[ 1 ]
343
+ ) ,
344
+ }
345
+ }
346
+
333
347
lazy_static ! {
334
348
static ref SCHEME : Scheme = {
335
349
let mut scheme: Scheme = Scheme ! {
@@ -367,6 +381,23 @@ mod tests {
367
381
)
368
382
. unwrap( ) ;
369
383
scheme
384
+ . add_function(
385
+ "concat" . into( ) ,
386
+ Function {
387
+ args: vec![ FunctionArg {
388
+ arg_kind: FunctionArgKind :: Field ,
389
+ val_type: Type :: Bytes ,
390
+ } ] ,
391
+ opt_args: vec![ FunctionOptArg {
392
+ arg_kind: FunctionArgKind :: Literal ,
393
+ default_value: RhsValue :: Bytes ( Bytes :: from( "" . to_owned( ) ) ) ,
394
+ } ] ,
395
+ return_type: Type :: Bytes ,
396
+ implementation: FunctionImpl :: new( concat_function) ,
397
+ } ,
398
+ )
399
+ . unwrap( ) ;
400
+ scheme
370
401
} ;
371
402
}
372
403
@@ -889,4 +920,105 @@ mod tests {
889
920
ctx. set_field_value ( "http.host" , "EXAMPLE.ORG" ) . unwrap ( ) ;
890
921
assert_eq ! ( expr. execute( ctx) , true ) ;
891
922
}
923
+
924
+ #[ test]
925
+ fn test_bytes_compare_with_concat_function ( ) {
926
+ let expr = assert_ok ! (
927
+ FieldExpr :: lex_with( r#"concat(http.host) == "example.org""# , & SCHEME ) ,
928
+ FieldExpr {
929
+ lhs: LhsFieldExpr :: FunctionCallExpr ( FunctionCallExpr {
930
+ name: String :: from( "concat" ) ,
931
+ function: SCHEME . get_function( "concat" ) . unwrap( ) ,
932
+ args: vec![
933
+ FunctionCallArgExpr :: LhsFieldExpr ( LhsFieldExpr :: Field ( field( "http.host" ) ) ) ,
934
+ FunctionCallArgExpr :: Literal ( RhsValue :: Bytes ( Bytes :: from( "" . to_owned( ) ) ) ) ,
935
+ ] ,
936
+ } ) ,
937
+ op: FieldOp :: Ordering {
938
+ op: OrderingOp :: Equal ,
939
+ rhs: RhsValue :: Bytes ( "example.org" . to_owned( ) . into( ) )
940
+ }
941
+ }
942
+ ) ;
943
+
944
+ assert_json ! (
945
+ expr,
946
+ {
947
+ "lhs" : {
948
+ "name" : "concat" ,
949
+ "args" : [
950
+ {
951
+ "kind" : "LhsFieldExpr" ,
952
+ "value" : "http.host"
953
+ } ,
954
+ {
955
+ "kind" : "Literal" ,
956
+ "value" : ""
957
+ } ,
958
+ ]
959
+ } ,
960
+ "op" : "Equal" ,
961
+ "rhs" : "example.org"
962
+ }
963
+ ) ;
964
+
965
+ let expr = expr. compile ( ) ;
966
+ let ctx = & mut ExecutionContext :: new ( & SCHEME ) ;
967
+
968
+ ctx. set_field_value ( "http.host" , "example.org" ) . unwrap ( ) ;
969
+ assert_eq ! ( expr. execute( ctx) , true ) ;
970
+
971
+ ctx. set_field_value ( "http.host" , "example.co.uk" ) . unwrap ( ) ;
972
+ assert_eq ! ( expr. execute( ctx) , false ) ;
973
+
974
+ let expr = assert_ok ! (
975
+ FieldExpr :: lex_with( r#"concat(http.host, ".org") == "example.org""# , & SCHEME ) ,
976
+ FieldExpr {
977
+ lhs: LhsFieldExpr :: FunctionCallExpr ( FunctionCallExpr {
978
+ name: String :: from( "concat" ) ,
979
+ function: SCHEME . get_function( "concat" ) . unwrap( ) ,
980
+ args: vec![
981
+ FunctionCallArgExpr :: LhsFieldExpr ( LhsFieldExpr :: Field ( field( "http.host" ) ) ) ,
982
+ FunctionCallArgExpr :: Literal ( RhsValue :: Bytes ( Bytes :: from(
983
+ ".org" . to_owned( )
984
+ ) ) ) ,
985
+ ] ,
986
+ } ) ,
987
+ op: FieldOp :: Ordering {
988
+ op: OrderingOp :: Equal ,
989
+ rhs: RhsValue :: Bytes ( "example.org" . to_owned( ) . into( ) )
990
+ }
991
+ }
992
+ ) ;
993
+
994
+ assert_json ! (
995
+ expr,
996
+ {
997
+ "lhs" : {
998
+ "name" : "concat" ,
999
+ "args" : [
1000
+ {
1001
+ "kind" : "LhsFieldExpr" ,
1002
+ "value" : "http.host"
1003
+ } ,
1004
+ {
1005
+ "kind" : "Literal" ,
1006
+ "value" : ".org"
1007
+ } ,
1008
+ ]
1009
+ } ,
1010
+ "op" : "Equal" ,
1011
+ "rhs" : "example.org"
1012
+ }
1013
+ ) ;
1014
+
1015
+ let expr = expr. compile ( ) ;
1016
+ let ctx = & mut ExecutionContext :: new ( & SCHEME ) ;
1017
+
1018
+ ctx. set_field_value ( "http.host" , "example" ) . unwrap ( ) ;
1019
+ assert_eq ! ( expr. execute( ctx) , true ) ;
1020
+
1021
+ ctx. set_field_value ( "http.host" , "cloudflare" ) . unwrap ( ) ;
1022
+ assert_eq ! ( expr. execute( ctx) , false ) ;
1023
+ }
892
1024
}
0 commit comments