@@ -19,12 +19,78 @@ pub extern "C-unwind" fn kclvm_net_split_host_port(
19
19
let kwargs = ptr_as_ref ( kwargs) ;
20
20
let ctx = mut_ptr_as_ref ( ctx) ;
21
21
22
- if let Some ( string) = get_call_arg_str ( args, kwargs, 0 , Some ( "ip_end_point" ) ) {
23
- let mut list = ValueRef :: list ( None ) ;
24
- for s in string. split ( ':' ) {
25
- list. list_append ( & ValueRef :: str ( s) ) ;
22
+ if let Some ( ip_end_point) = get_call_arg ( args, kwargs, 0 , Some ( "ip_end_point" ) ) {
23
+ if ip_end_point. is_none ( ) {
24
+ return ValueRef :: none ( ) . into_raw ( ctx) ;
25
+ }
26
+ let ip_end_point_str = ip_end_point. as_str ( ) ;
27
+ match ip_end_point_str. rsplit_once ( ':' ) {
28
+ None => panic ! (
29
+ "ip_end_point \" {}\" missing port" ,
30
+ ip_end_point_str. escape_default( )
31
+ ) ,
32
+ Some ( ( host, port) ) => {
33
+ if host. starts_with ( '[' ) {
34
+ match ip_end_point_str. find ( ']' ) {
35
+ None => panic ! (
36
+ "ip_end_point \" {}\" missing ']'" ,
37
+ ip_end_point_str. escape_default( )
38
+ ) ,
39
+ Some ( end) => {
40
+ if end > host. len ( ) || !ip_end_point_str[ end + 1 ..] . starts_with ( ':' ) {
41
+ panic ! (
42
+ "ip_end_point \" {}\" missing port" ,
43
+ ip_end_point_str. escape_default( )
44
+ ) ;
45
+ }
46
+ if end < host. len ( ) - 1 {
47
+ panic ! (
48
+ "ip_end_point \" {}\" too many colons" ,
49
+ ip_end_point_str. escape_default( )
50
+ ) ;
51
+ }
52
+ if ip_end_point_str[ 1 ..] . contains ( '[' ) {
53
+ panic ! (
54
+ "ip_end_point \" {}\" unexpected '['" ,
55
+ ip_end_point_str. escape_default( )
56
+ ) ;
57
+ }
58
+ if port. contains ( ']' ) {
59
+ panic ! (
60
+ "ip_end_point \" {}\" unexpected ']'" ,
61
+ ip_end_point_str. escape_default( )
62
+ ) ;
63
+ }
64
+ return ValueRef :: list ( Some ( & [
65
+ & ValueRef :: str ( & host[ 1 ..end] ) ,
66
+ & ValueRef :: str ( port) ,
67
+ ] ) )
68
+ . into_raw ( ctx) ;
69
+ }
70
+ }
71
+ }
72
+ if host. contains ( ':' ) {
73
+ panic ! (
74
+ "ip_end_point \" {}\" too many colons" ,
75
+ ip_end_point_str. escape_default( )
76
+ ) ;
77
+ }
78
+ if ip_end_point_str[ 1 ..] . contains ( '[' ) {
79
+ panic ! (
80
+ "ip_end_point \" {}\" unexpected '['" ,
81
+ ip_end_point_str. escape_default( )
82
+ ) ;
83
+ }
84
+ if ip_end_point_str. contains ( ']' ) {
85
+ panic ! (
86
+ "ip_end_point \" {}\" unexpected ']'" ,
87
+ ip_end_point_str. escape_default( )
88
+ ) ;
89
+ }
90
+ return ValueRef :: list ( Some ( & [ & ValueRef :: str ( host) , & ValueRef :: str ( port) ] ) )
91
+ . into_raw ( ctx) ;
92
+ }
26
93
}
27
- return list. into_raw ( ctx) ;
28
94
}
29
95
30
96
panic ! ( "split_host_port() missing 1 required positional argument: 'ip_end_point'" ) ;
@@ -43,14 +109,15 @@ pub extern "C-unwind" fn kclvm_net_join_host_port(
43
109
let kwargs = ptr_as_ref ( kwargs) ;
44
110
let ctx = mut_ptr_as_ref ( ctx) ;
45
111
46
- if let Some ( host) = get_call_arg_str ( args, kwargs, 0 , Some ( "host" ) ) {
47
- if let Some ( port) = args. arg_i_int ( 1 , None ) . or ( kwargs. kwarg_int ( "port" , None ) ) {
48
- let s = format ! ( "{host}:{port}" ) ;
49
- return ValueRef :: str ( s. as_ref ( ) ) . into_raw ( ctx) ;
50
- }
51
- if let Some ( port) = args. arg_i_str ( 1 , None ) . or ( kwargs. kwarg_str ( "port" , None ) ) {
52
- let s = format ! ( "{host}:{port}" ) ;
53
- return ValueRef :: str ( s. as_ref ( ) ) . into_raw ( ctx) ;
112
+ if let Some ( host) = get_call_arg ( args, kwargs, 0 , Some ( "host" ) ) {
113
+ if let Some ( port) = get_call_arg ( args, kwargs, 1 , Some ( "port" ) ) {
114
+ if host. is_none ( ) || port. is_none ( ) {
115
+ return ValueRef :: none ( ) . into_raw ( ctx) ;
116
+ }
117
+ if host. as_str ( ) . contains ( ':' ) {
118
+ return ValueRef :: str ( format ! ( "[{host}]:{port}" ) . as_ref ( ) ) . into_raw ( ctx) ;
119
+ }
120
+ return ValueRef :: str ( format ! ( "{host}:{port}" ) . as_ref ( ) ) . into_raw ( ctx) ;
54
121
}
55
122
}
56
123
panic ! ( "join_host_port() missing 2 required positional arguments: 'host' and 'port'" ) ;
@@ -602,3 +669,231 @@ pub extern "C-unwind" fn kclvm_net_is_unspecified_IP(
602
669
}
603
670
panic ! ( "is_unspecified_IP() missing 1 required positional argument: 'ip'" ) ;
604
671
}
672
+
673
+ #[ cfg( test) ]
674
+ mod test_net {
675
+ use super :: * ;
676
+
677
+ #[ test]
678
+ fn test_split_host_port ( ) {
679
+ let cases = [
680
+ ( ValueRef :: none ( ) , ValueRef :: none ( ) ) ,
681
+ (
682
+ ValueRef :: str ( "invalid.invalid:21" ) ,
683
+ ValueRef :: list ( Some ( & [
684
+ & ValueRef :: str ( "invalid.invalid" ) ,
685
+ & ValueRef :: str ( "21" ) ,
686
+ ] ) ) ,
687
+ ) ,
688
+ (
689
+ ValueRef :: str ( "192.0.2.1:14" ) ,
690
+ ValueRef :: list ( Some ( & [ & ValueRef :: str ( "192.0.2.1" ) , & ValueRef :: str ( "14" ) ] ) ) ,
691
+ ) ,
692
+ (
693
+ ValueRef :: str ( "[2001:db8::]:80" ) ,
694
+ ValueRef :: list ( Some ( & [ & ValueRef :: str ( "2001:db8::" ) , & ValueRef :: str ( "80" ) ] ) ) ,
695
+ ) ,
696
+ ] ;
697
+ let mut ctx = Context :: default ( ) ;
698
+ for ( ip_end_point, expected) in cases. iter ( ) {
699
+ unsafe {
700
+ let actual = & * kclvm_net_split_host_port (
701
+ & mut ctx,
702
+ & ValueRef :: list ( Some ( & [ & ip_end_point] ) ) ,
703
+ & ValueRef :: dict ( None ) ,
704
+ ) ;
705
+ assert_eq ! ( expected, actual) ;
706
+ }
707
+ unsafe {
708
+ let actual = & * kclvm_net_split_host_port (
709
+ & mut ctx,
710
+ & ValueRef :: list ( None ) ,
711
+ & ValueRef :: dict ( Some ( & [ ( "ip_end_point" , ip_end_point) ] ) ) ,
712
+ ) ;
713
+ assert_eq ! ( expected, actual) ;
714
+ }
715
+ }
716
+ }
717
+
718
+ #[ test]
719
+ fn test_split_host_port_invalid ( ) {
720
+ let prev_hook = std:: panic:: take_hook ( ) ;
721
+ // Disable print panic info in stderr.
722
+ std:: panic:: set_hook ( Box :: new ( |_| { } ) ) ;
723
+ assert_panic (
724
+ "split_host_port() missing 1 required positional argument: 'ip_end_point'" ,
725
+ || {
726
+ let mut ctx = Context :: new ( ) ;
727
+ let args = ValueRef :: list ( None ) . into_raw ( & mut ctx) ;
728
+ let kwargs = ValueRef :: dict ( None ) . into_raw ( & mut ctx) ;
729
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, kwargs) ;
730
+ } ,
731
+ ) ;
732
+ assert_panic ( "ip_end_point \" test-host\" missing port" , || {
733
+ let ctx = Context :: new ( ) ;
734
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "test-host" ) ] ) ) ;
735
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
736
+ } ) ;
737
+ assert_panic ( "ip_end_point \" test-host:7:80\" too many colons" , || {
738
+ let ctx = Context :: new ( ) ;
739
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "test-host:7:80" ) ] ) ) ;
740
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
741
+ } ) ;
742
+ assert_panic ( "ip_end_point \" [2001:db8::]\" missing port" , || {
743
+ let ctx = Context :: new ( ) ;
744
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8::]" ) ] ) ) ;
745
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
746
+ } ) ;
747
+ assert_panic ( "ip_end_point \" [2001:db8::]80\" missing port" , || {
748
+ let ctx = Context :: new ( ) ;
749
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8::]80" ) ] ) ) ;
750
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
751
+ } ) ;
752
+ assert_panic ( "ip_end_point \" [2001:db8::]9:80\" missing port" , || {
753
+ let ctx = Context :: new ( ) ;
754
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8::]9:80" ) ] ) ) ;
755
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
756
+ } ) ;
757
+ assert_panic ( "ip_end_point \" [2001:db8::]:9:80\" too many colons" , || {
758
+ let ctx = Context :: new ( ) ;
759
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8::]:9:80" ) ] ) ) ;
760
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
761
+ } ) ;
762
+ assert_panic ( "ip_end_point \" [2001:db8:::80\" missing ']'" , || {
763
+ let ctx = Context :: new ( ) ;
764
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8:::80" ) ] ) ) ;
765
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
766
+ } ) ;
767
+ assert_panic ( "ip_end_point \" t[est-host:80\" unexpected '['" , || {
768
+ let ctx = Context :: new ( ) ;
769
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "t[est-host:80" ) ] ) ) ;
770
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
771
+ } ) ;
772
+ assert_panic ( "ip_end_point \" ]test-host:80\" unexpected ']'" , || {
773
+ let ctx = Context :: new ( ) ;
774
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "]test-host:80" ) ] ) ) ;
775
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
776
+ } ) ;
777
+ assert_panic ( "ip_end_point \" [[2001:db8::]:80\" unexpected '['" , || {
778
+ let ctx = Context :: new ( ) ;
779
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[[2001:db8::]:80" ) ] ) ) ;
780
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
781
+ } ) ;
782
+ assert_panic ( "ip_end_point \" [2001:db8::]:]80\" unexpected ']'" , || {
783
+ let ctx = Context :: new ( ) ;
784
+ let args = & ValueRef :: list ( Some ( & [ & ValueRef :: str ( "[2001:db8::]:]80" ) ] ) ) ;
785
+ kclvm_net_split_host_port ( ctx. into_raw ( ) , args, & ValueRef :: dict ( None ) ) ;
786
+ } ) ;
787
+ std:: panic:: set_hook ( prev_hook) ;
788
+ }
789
+
790
+ #[ test]
791
+ fn test_join_host_port ( ) {
792
+ let cases = [
793
+ ( ValueRef :: none ( ) , ValueRef :: none ( ) , ValueRef :: none ( ) ) ,
794
+ ( ValueRef :: none ( ) , ValueRef :: int ( 21 ) , ValueRef :: none ( ) ) ,
795
+ ( ValueRef :: none ( ) , ValueRef :: str ( "21" ) , ValueRef :: none ( ) ) ,
796
+ (
797
+ ValueRef :: str ( "invalid.invalid" ) ,
798
+ ValueRef :: none ( ) ,
799
+ ValueRef :: none ( ) ,
800
+ ) ,
801
+ (
802
+ ValueRef :: str ( "invalid.invalid" ) ,
803
+ ValueRef :: int ( 21 ) ,
804
+ ValueRef :: str ( "invalid.invalid:21" ) ,
805
+ ) ,
806
+ (
807
+ ValueRef :: str ( "invalid.invalid" ) ,
808
+ ValueRef :: str ( "21" ) ,
809
+ ValueRef :: str ( "invalid.invalid:21" ) ,
810
+ ) ,
811
+ (
812
+ ValueRef :: str ( "192.0.2.1" ) ,
813
+ ValueRef :: int ( 14 ) ,
814
+ ValueRef :: str ( "192.0.2.1:14" ) ,
815
+ ) ,
816
+ (
817
+ ValueRef :: str ( "192.0.2.1" ) ,
818
+ ValueRef :: str ( "14" ) ,
819
+ ValueRef :: str ( "192.0.2.1:14" ) ,
820
+ ) ,
821
+ (
822
+ ValueRef :: str ( "2001:db8::" ) ,
823
+ ValueRef :: int ( 14 ) ,
824
+ ValueRef :: str ( "[2001:db8::]:14" ) ,
825
+ ) ,
826
+ (
827
+ ValueRef :: str ( "2001:db8::" ) ,
828
+ ValueRef :: str ( "14" ) ,
829
+ ValueRef :: str ( "[2001:db8::]:14" ) ,
830
+ ) ,
831
+ ] ;
832
+ let mut ctx = Context :: default ( ) ;
833
+ for ( host, port, expected) in cases. iter ( ) {
834
+ unsafe {
835
+ let actual = & * kclvm_net_join_host_port (
836
+ & mut ctx,
837
+ & ValueRef :: list ( Some ( & [ & host, & port] ) ) ,
838
+ & ValueRef :: dict ( None ) ,
839
+ ) ;
840
+ assert_eq ! ( expected, actual) ;
841
+ }
842
+ unsafe {
843
+ let actual = & * kclvm_net_join_host_port (
844
+ & mut ctx,
845
+ & ValueRef :: list ( None ) ,
846
+ & ValueRef :: dict ( Some ( & [ ( "host" , host) , ( "port" , port) ] ) ) ,
847
+ ) ;
848
+ assert_eq ! ( expected, actual) ;
849
+ }
850
+ }
851
+ }
852
+
853
+ #[ test]
854
+ fn test_join_host_port_invalid ( ) {
855
+ let prev_hook = std:: panic:: take_hook ( ) ;
856
+ // Disable print panic info in stderr.
857
+ std:: panic:: set_hook ( Box :: new ( |_| { } ) ) ;
858
+ assert_panic (
859
+ "join_host_port() missing 2 required positional arguments: 'host' and 'port'" ,
860
+ || {
861
+ let mut ctx = Context :: new ( ) ;
862
+ let args = ValueRef :: list ( None ) . into_raw ( & mut ctx) ;
863
+ let kwargs = ValueRef :: dict ( None ) . into_raw ( & mut ctx) ;
864
+ kclvm_net_join_host_port ( ctx. into_raw ( ) , args, kwargs) ;
865
+ } ,
866
+ ) ;
867
+ assert_panic (
868
+ "join_host_port() missing 2 required positional arguments: 'host' and 'port'" ,
869
+ || {
870
+ let mut ctx = Context :: new ( ) ;
871
+ let args =
872
+ ValueRef :: list ( Some ( & [ & ValueRef :: str ( "invalid.invalid" ) ] ) ) . into_raw ( & mut ctx) ;
873
+ let kwargs = ValueRef :: dict ( None ) . into_raw ( & mut ctx) ;
874
+ kclvm_net_join_host_port ( ctx. into_raw ( ) , args, kwargs) ;
875
+ } ,
876
+ ) ;
877
+ assert_panic (
878
+ "join_host_port() missing 2 required positional arguments: 'host' and 'port'" ,
879
+ || {
880
+ let mut ctx = Context :: new ( ) ;
881
+ let args = ValueRef :: list ( None ) . into_raw ( & mut ctx) ;
882
+ let kwargs = ValueRef :: dict ( Some ( & [ ( "host" , & ValueRef :: str ( "invalid.invalid" ) ) ] ) )
883
+ . into_raw ( & mut ctx) ;
884
+ kclvm_net_join_host_port ( ctx. into_raw ( ) , args, kwargs) ;
885
+ } ,
886
+ ) ;
887
+ assert_panic (
888
+ "join_host_port() missing 2 required positional arguments: 'host' and 'port'" ,
889
+ || {
890
+ let mut ctx = Context :: new ( ) ;
891
+ let args = ValueRef :: list ( None ) . into_raw ( & mut ctx) ;
892
+ let kwargs =
893
+ ValueRef :: dict ( Some ( & [ ( "port" , & ValueRef :: str ( "80" ) ) ] ) ) . into_raw ( & mut ctx) ;
894
+ kclvm_net_join_host_port ( ctx. into_raw ( ) , args, kwargs) ;
895
+ } ,
896
+ ) ;
897
+ std:: panic:: set_hook ( prev_hook) ;
898
+ }
899
+ }
0 commit comments