@@ -10,6 +10,7 @@ This Source Code Form is subject to the terms of the
1010using System . Collections . Generic ;
1111using System . Linq ;
1212using System . Net ;
13+ using System . Runtime . InteropServices ;
1314
1415namespace ScriptEngine . HostedScript . Library . Http
1516{
@@ -20,154 +21,151 @@ namespace ScriptEngine.HostedScript.Library.Http
2021 [ ContextClass ( "ИнтернетПрокси" , "InternetProxy" ) ]
2122 public class InternetProxyContext : AutoContext < InternetProxyContext >
2223 {
24+ private Dictionary < string , IWebProxy > _proxies = new Dictionary < string , IWebProxy > ( ) ;
25+ private const string LINUX_ENV_HTTP = "http_proxy" ;
26+ private const string LINUX_ENV_HTTPS = "https_proxy" ;
27+
2328 private ArrayImpl _bypassProxyOnAddresses ;
2429 private bool _bypassLocal ;
2530
26- private Dictionary < string , ProxySettings > _proxies = new Dictionary < string , ProxySettings > ( ) ;
27-
28- private class ProxySettings
29- {
30- public string server ;
31- public int port ;
32- public bool useOSAuthentication ;
33- public IWebProxy proxy ;
34- public NetworkCredential creds ;
35- }
36-
37- private const string PROTO_HTTP = "http" ;
38- private const string PROTO_HTTPS = "https" ;
39-
4031 public InternetProxyContext ( bool useDefault )
4132 {
42- var settings = new ProxySettings ( ) ;
33+ var emptyProxy = new WebProxy ( ) ;
34+ _bypassLocal = false ;
35+ _bypassProxyOnAddresses = new ArrayImpl ( ) ;
36+
4337 if ( useDefault )
4438 {
45- settings . proxy = WebRequest . GetSystemWebProxy ( ) ;
46- settings . creds = ( NetworkCredential ) System . Net . CredentialCache . DefaultCredentials ;
47- if ( settings . creds != null )
48- settings . proxy . Credentials = settings . creds ;
39+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
40+ {
41+ var httpEnv = System . Environment . GetEnvironmentVariable ( LINUX_ENV_HTTP ) ;
42+ _proxies [ Uri . UriSchemeHttp ] = httpEnv == null ? emptyProxy :
43+ _proxies [ Uri . UriSchemeHttp ] = GetProxyFromEnvironmentVariable ( httpEnv ) ;
44+
45+ var httpsEnv = System . Environment . GetEnvironmentVariable ( LINUX_ENV_HTTPS ) ;
46+ _proxies [ Uri . UriSchemeHttps ] = httpsEnv == null ? emptyProxy :
47+ _proxies [ Uri . UriSchemeHttps ] = GetProxyFromEnvironmentVariable ( httpEnv ) ;
48+ }
4949 else
50- settings . creds = new NetworkCredential ( ) ;
50+ {
51+ var defaultProxy = WebRequest . GetSystemWebProxy ( ) ;
52+ defaultProxy . Credentials = CredentialCache . DefaultNetworkCredentials ;
5153
52- _proxies [ PROTO_HTTP ] = settings ;
53- _proxies [ PROTO_HTTPS ] = settings ;
54+ _proxies [ Uri . UriSchemeHttp ] = defaultProxy ;
55+ _proxies [ Uri . UriSchemeHttps ] = defaultProxy ;
56+ }
5457 }
5558 else
5659 {
57- _bypassLocal = false ;
58- settings . server = String . Empty ;
59- settings . creds = new NetworkCredential ( ) ;
60-
61- _proxies [ PROTO_HTTP ] = settings ;
62- _proxies [ PROTO_HTTPS ] = settings ;
60+ _proxies [ Uri . UriSchemeHttp ] = emptyProxy ;
61+ _proxies [ Uri . UriSchemeHttps ] = emptyProxy ;
6362 }
63+ }
6464
65- _bypassProxyOnAddresses = new ArrayImpl ( ) ;
65+ private static WebProxy GetProxyFromEnvironmentVariable ( string envVariable )
66+ {
67+ var proxyBuilder = new UriBuilder ( envVariable ) ;
68+ var proxyUri = new Uri ( proxyBuilder . Uri . GetComponents ( UriComponents . HttpRequestUrl , UriFormat . UriEscaped ) ) ;
69+ var proxyCredentials = proxyBuilder . UserName . Equals ( string . Empty )
70+ ? CredentialCache . DefaultNetworkCredentials
71+ : GetBasicCredential ( proxyUri , proxyBuilder . UserName , proxyBuilder . Password ) ;
72+ return new WebProxy ( proxyUri , true , new string [ ] { } , proxyCredentials ) ;
6673 }
6774
68- public IWebProxy GetProxy ( string protocol )
75+ private static ICredentials GetBasicCredential ( Uri uri , string username , string password )
6976 {
70- var settings = GetSettings ( protocol ) ;
71- IWebProxy returnProxy ;
77+ var credential = new NetworkCredential ( username , password ) ;
78+ var cache = new CredentialCache { { uri , "Basic" , credential } } ;
79+ return cache ;
80+ }
7281
73- if ( settings . proxy == null )
74- {
75- if ( String . IsNullOrEmpty ( settings . server ) )
76- throw new RuntimeException ( "Не заданы настройки прокси-сервера для протокола, используемого в запросе" ) ;
77-
78- var wp = new WebProxy ( settings . server , settings . port ) ;
79- wp . Credentials = settings . creds ;
80- wp . BypassList = _bypassProxyOnAddresses . Select ( x => x . AsString ( ) ) . ToArray ( ) ;
81- wp . BypassProxyOnLocal = _bypassLocal ;
82- settings . proxy = wp ;
83- returnProxy = wp ;
84- }
85- else
86- {
87- returnProxy = _proxies [ protocol ] . proxy ;
88- }
89-
90- return returnProxy ;
82+ public IWebProxy GetProxy ( string protocol )
83+ {
84+ if ( ! ProtocolNameIsValid ( protocol ) )
85+ throw RuntimeException . InvalidArgumentValue ( ) ;
86+ return _proxies [ protocol ] ;
9187 }
9288
9389 [ ContextMethod ( "Пользователь" , "User" ) ]
9490 public string User ( string protocol )
9591 {
96- return GetSettings ( protocol ) . creds . UserName ;
92+ var proxy = GetProxy ( protocol ) as WebProxy ;
93+ return proxy ? . Credentials . GetCredential ( proxy . Address , "Basic" ) . UserName ?? string . Empty ;
9794 }
9895
9996 [ ContextMethod ( "Пароль" , "Password" ) ]
10097 public string Password ( string protocol )
10198 {
102- return GetSettings ( protocol ) . creds . Password ;
99+ var proxy = GetProxy ( protocol ) as WebProxy ;
100+ return proxy ? . Credentials . GetCredential ( proxy . Address , "Basic" ) . Password ?? string . Empty ;
103101 }
104102
105103 [ ContextMethod ( "Сервер" , "Server" ) ]
106104 public string Server ( string protocol )
107105 {
108- return GetSettings ( protocol ) . server ;
106+ const UriComponents serverComponents = UriComponents . Scheme | UriComponents . Host | UriComponents . PathAndQuery ;
107+ var proxy = GetProxy ( protocol ) as WebProxy ;
108+ return proxy ? . Address . GetComponents ( serverComponents , UriFormat . UriEscaped ) ?? string . Empty ;
109109 }
110110
111111 [ ContextMethod ( "Порт" , "Password" ) ]
112112 public int Port ( string protocol )
113113 {
114- return GetSettings ( protocol ) . port ;
114+ var proxy = GetProxy ( protocol ) as WebProxy ;
115+ return proxy ? . Address . Port ?? 0 ;
115116 }
116117
117118 [ ContextMethod ( "Установить" , "Set" ) ]
118119 public void Set ( string protocol , string server , int port = 0 , string username = "" , string password = "" , bool useOSAuthentication = true )
119120 {
121+ protocol = protocol . ToLower ( ) ;
120122 if ( ! ProtocolNameIsValid ( protocol ) )
121123 throw RuntimeException . InvalidArgumentValue ( ) ;
124+
125+ var builderServer = new UriBuilder ( server ) ;
126+ if ( builderServer . Scheme . Equals ( string . Empty ) )
127+ builderServer . Scheme = protocol ;
128+
129+ if ( port != 0 )
130+ builderServer . Port = port ;
131+
132+ var proxyCredentials = useOSAuthentication ? CredentialCache . DefaultNetworkCredentials :
133+ GetBasicCredential ( builderServer . Uri , username , password ) ;
122134
123- var settings = new ProxySettings
124- {
125- server = server ,
126- port = port ,
127- creds = new NetworkCredential ( username , password ) ,
128- useOSAuthentication = useOSAuthentication
129- } ;
130-
131- _proxies [ protocol ] = settings ;
135+ _proxies [ protocol ] = new WebProxy ( builderServer . Uri , _bypassLocal ,
136+ _bypassProxyOnAddresses ? . Select ( x => x . AsString ( ) ) . ToArray ( ) ?? new string [ ] { } , proxyCredentials ) ;
132137 }
133138
134139 [ ContextProperty ( "НеИспользоватьПроксиДляАдресов" , "BypassProxyOnAddresses" ) ]
135140 public ArrayImpl BypassProxyList
136141 {
137- get
138- {
139- return _bypassProxyOnAddresses ;
140- }
142+ get => _bypassProxyOnAddresses ;
141143 set
142144 {
143145 _bypassProxyOnAddresses = value ;
146+ var bypassList = _bypassProxyOnAddresses ? . Select ( x => x . AsString ( ) ) . ToArray ( ) ?? new string [ ] { } ;
147+ foreach ( var kv in _proxies )
148+ if ( kv . Value is WebProxy proxy )
149+ proxy . BypassList = bypassList ;
144150 }
145151 }
146152
147153 [ ContextProperty ( "НеИспользоватьПроксиДляЛокальныхАдресов" , "BypassProxyOnLocal" ) ]
148154 public bool BypassProxyOnLocal
149155 {
150- get
151- {
152- return _bypassLocal ;
153- }
156+ get => _bypassLocal ;
154157 set
155158 {
156159 _bypassLocal = value ;
160+ foreach ( var kv in _proxies )
161+ if ( kv . Value is WebProxy proxy )
162+ proxy . BypassProxyOnLocal = _bypassLocal ;
157163 }
158164 }
159165
160- private ProxySettings GetSettings ( string protocol )
161- {
162- if ( ! ProtocolNameIsValid ( protocol ) )
163- throw RuntimeException . InvalidArgumentValue ( ) ;
164-
165- return _proxies [ protocol ] ;
166- }
167-
168166 private static bool ProtocolNameIsValid ( string protocol )
169167 {
170- return StringComparer . OrdinalIgnoreCase . Compare ( protocol , PROTO_HTTP ) == 0 || StringComparer . OrdinalIgnoreCase . Compare ( protocol , PROTO_HTTPS ) == 0 ;
168+ return Uri . UriSchemeHttp . Equals ( protocol ) || Uri . UriSchemeHttps . Equals ( protocol ) ;
171169 }
172170
173171 [ ScriptConstructor ( Name = "Формирование неинициализированного объекта" ) ]
0 commit comments