@@ -80,6 +80,8 @@ use shadowsocks::{
8080use crate :: acl:: AccessControl ;
8181#[ cfg( feature = "local-dns" ) ]
8282use crate :: local:: dns:: NameServerAddr ;
83+ #[ cfg( feature = "local-http" ) ]
84+ use crate :: local:: http:: config:: HttpAuthConfig ;
8385#[ cfg( feature = "local" ) ]
8486use crate :: local:: socks:: config:: Socks5AuthConfig ;
8587
@@ -323,6 +325,11 @@ struct SSLocalExtConfig {
323325 #[ serde( skip_serializing_if = "Option::is_none" ) ]
324326 socks5_auth_config_path : Option < String > ,
325327
328+ /// HTTP
329+ #[ cfg( feature = "local" ) ]
330+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
331+ http_auth_config_path : Option < String > ,
332+
326333 /// Fake DNS
327334 #[ cfg( feature = "local-fake-dns" ) ]
328335 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -1038,6 +1045,10 @@ pub struct LocalConfig {
10381045 #[ cfg( feature = "local" ) ]
10391046 pub socks5_auth : Socks5AuthConfig ,
10401047
1048+ /// HTTP Authentication configuration
1049+ #[ cfg( feature = "local" ) ]
1050+ pub http_auth : HttpAuthConfig ,
1051+
10411052 /// Fake DNS record expire seconds
10421053 #[ cfg( feature = "local-fake-dns" ) ]
10431054 pub fake_dns_record_expire_duration : Option < Duration > ,
@@ -1108,6 +1119,9 @@ impl LocalConfig {
11081119 #[ cfg( feature = "local" ) ]
11091120 socks5_auth : Socks5AuthConfig :: default ( ) ,
11101121
1122+ #[ cfg( feature = "local-http" ) ]
1123+ http_auth : HttpAuthConfig :: default ( ) ,
1124+
11111125 #[ cfg( feature = "local-fake-dns" ) ]
11121126 fake_dns_record_expire_duration : None ,
11131127 #[ cfg( feature = "local-fake-dns" ) ]
@@ -1832,6 +1846,11 @@ impl Config {
18321846 local_config. socks5_auth = Socks5AuthConfig :: load_from_file ( & socks5_auth_config_path) ?;
18331847 }
18341848
1849+ #[ cfg( feature = "local-http" ) ]
1850+ if let Some ( http_auth_config_path) = local. http_auth_config_path {
1851+ local_config. http_auth = HttpAuthConfig :: load_from_file ( & http_auth_config_path) ?;
1852+ }
1853+
18351854 #[ cfg( feature = "local-fake-dns" ) ]
18361855 {
18371856 if let Some ( d) = local. fake_dns_record_expire_duration {
@@ -2390,15 +2409,16 @@ impl Config {
23902409 // Security
23912410 if let Some ( sec) = config. security
23922411 && let Some ( replay_attack) = sec. replay_attack
2393- && let Some ( policy) = replay_attack. policy {
2394- match policy. parse :: < ReplayAttackPolicy > ( ) {
2395- Ok ( p) => nconfig. security . replay_attack . policy = p,
2396- Err ( ..) => {
2397- let err = Error :: new ( ErrorKind :: Invalid , "invalid replay attack policy" , None ) ;
2398- return Err ( err) ;
2399- }
2400- }
2412+ && let Some ( policy) = replay_attack. policy
2413+ {
2414+ match policy. parse :: < ReplayAttackPolicy > ( ) {
2415+ Ok ( p) => nconfig. security . replay_attack . policy = p,
2416+ Err ( ..) => {
2417+ let err = Error :: new ( ErrorKind :: Invalid , "invalid replay attack policy" , None ) ;
2418+ return Err ( err) ;
24012419 }
2420+ }
2421+ }
24022422
24032423 if let Some ( balancer) = config. balancer {
24042424 nconfig. balancer = BalancerConfig {
@@ -2619,16 +2639,18 @@ impl Config {
26192639
26202640 // Balancer related checks
26212641 if let Some ( rtt) = self . balancer . max_server_rtt
2622- && rtt. as_secs ( ) == 0 {
2623- let err = Error :: new ( ErrorKind :: Invalid , "balancer.max_server_rtt must be > 0" , None ) ;
2624- return Err ( err) ;
2625- }
2642+ && rtt. as_secs ( ) == 0
2643+ {
2644+ let err = Error :: new ( ErrorKind :: Invalid , "balancer.max_server_rtt must be > 0" , None ) ;
2645+ return Err ( err) ;
2646+ }
26262647
26272648 if let Some ( intv) = self . balancer . check_interval
2628- && intv. as_secs ( ) == 0 {
2629- let err = Error :: new ( ErrorKind :: Invalid , "balancer.check_interval must be > 0" , None ) ;
2630- return Err ( err) ;
2631- }
2649+ && intv. as_secs ( ) == 0
2650+ {
2651+ let err = Error :: new ( ErrorKind :: Invalid , "balancer.check_interval must be > 0" , None ) ;
2652+ return Err ( err) ;
2653+ }
26322654 }
26332655
26342656 if self . config_type . is_server ( ) && self . server . is_empty ( ) {
@@ -2664,10 +2686,11 @@ impl Config {
26642686
26652687 // Plugin shouldn't be an empty string
26662688 if let Some ( plugin) = server. plugin ( )
2667- && plugin. plugin . trim ( ) . is_empty ( ) {
2668- let err = Error :: new ( ErrorKind :: Malformed , "`plugin` shouldn't be an empty string" , None ) ;
2669- return Err ( err) ;
2670- }
2689+ && plugin. plugin . trim ( ) . is_empty ( )
2690+ {
2691+ let err = Error :: new ( ErrorKind :: Malformed , "`plugin` shouldn't be an empty string" , None ) ;
2692+ return Err ( err) ;
2693+ }
26712694
26722695 // Server's domain name shouldn't be an empty string
26732696 match server. addr ( ) {
@@ -2899,6 +2922,9 @@ impl fmt::Display for Config {
28992922 #[ cfg( feature = "local" ) ]
29002923 socks5_auth_config_path : None ,
29012924
2925+ #[ cfg( feature = "local-http" ) ]
2926+ http_auth_config_path : None ,
2927+
29022928 #[ cfg( feature = "local-fake-dns" ) ]
29032929 fake_dns_record_expire_duration : local. fake_dns_record_expire_duration . map ( |d| d. as_secs ( ) ) ,
29042930 #[ cfg( feature = "local-fake-dns" ) ]
@@ -3068,20 +3094,22 @@ impl fmt::Display for Config {
30683094 }
30693095
30703096 if jconf. method . is_none ( )
3071- && let Some ( ref m) = m. method {
3072- jconf. method = Some ( m. to_string ( ) ) ;
3073- }
3097+ && let Some ( ref m) = m. method
3098+ {
3099+ jconf. method = Some ( m. to_string ( ) ) ;
3100+ }
30743101
30753102 if jconf. plugin . is_none ( )
3076- && let Some ( ref p) = m. plugin {
3077- jconf. plugin = Some ( p. plugin . clone ( ) ) ;
3078- if let Some ( ref o) = p. plugin_opts {
3079- jconf. plugin_opts = Some ( o. clone ( ) ) ;
3080- }
3081- if !p. plugin_args . is_empty ( ) {
3082- jconf. plugin_args = Some ( p. plugin_args . clone ( ) ) ;
3083- }
3103+ && let Some ( ref p) = m. plugin
3104+ {
3105+ jconf. plugin = Some ( p. plugin . clone ( ) ) ;
3106+ if let Some ( ref o) = p. plugin_opts {
3107+ jconf. plugin_opts = Some ( o. clone ( ) ) ;
30843108 }
3109+ if !p. plugin_args . is_empty ( ) {
3110+ jconf. plugin_args = Some ( p. plugin_args . clone ( ) ) ;
3111+ }
3112+ }
30853113 }
30863114
30873115 if self . no_delay {
@@ -3188,17 +3216,18 @@ impl fmt::Display for Config {
31883216/// It will return the original value if fails to read `${VAR_NAME}`.
31893217pub fn read_variable_field_value ( value : & str ) -> Cow < ' _ , str > {
31903218 if let Some ( left_over) = value. strip_prefix ( "${" )
3191- && let Some ( var_name) = left_over. strip_suffix ( '}' ) {
3192- match env :: var ( var_name ) {
3193- Ok ( value ) => return value . into ( ) ,
3194- Err ( err ) => {
3195- warn ! (
3196- "couldn't read password from environment variable {}, error: {}" ,
3197- var_name , err
3198- ) ;
3199- }
3219+ && let Some ( var_name) = left_over. strip_suffix ( '}' )
3220+ {
3221+ match env :: var ( var_name ) {
3222+ Ok ( value ) => return value . into ( ) ,
3223+ Err ( err ) => {
3224+ warn ! (
3225+ "couldn't read password from environment variable {}, error: {}" ,
3226+ var_name , err
3227+ ) ;
32003228 }
32013229 }
3230+ }
32023231
32033232 value. into ( )
32043233}
0 commit comments