Skip to content

Commit 43e0a4f

Browse files
authored
Merge pull request #1111 from RedMammoth/hotfix/fix-1110
Fix #1110
2 parents fe5e591 + ea9d363 commit 43e0a4f

File tree

2 files changed

+88
-82
lines changed

2 files changed

+88
-82
lines changed

src/ScriptEngine.HostedScript/Library/Http/InternetProxyContext.cs

Lines changed: 86 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -20,154 +20,160 @@ namespace ScriptEngine.HostedScript.Library.Http
2020
[ContextClass("ИнтернетПрокси", "InternetProxy")]
2121
public class InternetProxyContext : AutoContext<InternetProxyContext>
2222
{
23+
private Dictionary<string, IWebProxy> _proxies = new Dictionary<string, IWebProxy>();
24+
private const string LINUX_ENV_HTTP = "http_proxy";
25+
private const string LINUX_ENV_HTTPS = "https_proxy";
26+
private const string LINUX_ENV_NO_PROXY = "no_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 (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
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+
49+
var noProxy = System.Environment.GetEnvironmentVariable(LINUX_ENV_NO_PROXY) ?? string.Empty;
50+
var separator = new[] {',', ' '};
51+
var byPassList = noProxy.Split(separator, StringSplitOptions.RemoveEmptyEntries);
52+
foreach (var uri in byPassList)
53+
_bypassProxyOnAddresses.Add(ValueFactory.Create(uri));
54+
foreach (var proxy in _proxies.Values.Cast<WebProxy>())
55+
proxy.BypassList = byPassList;
56+
}
4957
else
50-
settings.creds = new NetworkCredential();
58+
{
59+
var defaultProxy = WebRequest.GetSystemWebProxy();
60+
defaultProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
5161

52-
_proxies[PROTO_HTTP] = settings;
53-
_proxies[PROTO_HTTPS] = settings;
62+
_proxies[Uri.UriSchemeHttp] = defaultProxy;
63+
_proxies[Uri.UriSchemeHttps] = defaultProxy;
64+
}
5465
}
5566
else
5667
{
57-
_bypassLocal = false;
58-
settings.server = String.Empty;
59-
settings.creds = new NetworkCredential();
60-
61-
_proxies[PROTO_HTTP] = settings;
62-
_proxies[PROTO_HTTPS] = settings;
68+
_proxies[Uri.UriSchemeHttp] = emptyProxy;
69+
_proxies[Uri.UriSchemeHttps] = emptyProxy;
6370
}
71+
}
6472

65-
_bypassProxyOnAddresses = new ArrayImpl();
73+
private static WebProxy GetProxyFromEnvironmentVariable(string envVariable)
74+
{
75+
var proxyBuilder = new UriBuilder(envVariable);
76+
var proxyUri = new Uri(proxyBuilder.Uri.GetComponents(UriComponents.HttpRequestUrl, UriFormat.UriEscaped));
77+
var proxyCredentials = proxyBuilder.UserName.Equals(string.Empty)
78+
? CredentialCache.DefaultNetworkCredentials
79+
: GetBasicCredential(proxyUri, proxyBuilder.UserName, proxyBuilder.Password);
80+
return new WebProxy(proxyUri, true, new string[]{}, proxyCredentials);
6681
}
6782

68-
public IWebProxy GetProxy(string protocol)
83+
private static ICredentials GetBasicCredential(Uri uri, string username, string password)
6984
{
70-
var settings = GetSettings(protocol);
71-
IWebProxy returnProxy;
85+
var credential = new NetworkCredential(username, password);
86+
var cache = new CredentialCache {{uri, "Basic", credential}};
87+
return cache;
88+
}
7289

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;
90+
public IWebProxy GetProxy(string protocol)
91+
{
92+
if(!ProtocolNameIsValid(protocol))
93+
throw RuntimeException.InvalidArgumentValue();
94+
return _proxies[protocol];
9195
}
9296

9397
[ContextMethod("Пользователь","User")]
9498
public string User(string protocol)
9599
{
96-
return GetSettings(protocol).creds.UserName;
100+
var proxy = GetProxy(protocol) as WebProxy;
101+
return proxy?.Credentials.GetCredential(proxy.Address, "Basic").UserName ?? string.Empty;
97102
}
98103

99104
[ContextMethod("Пароль", "Password")]
100105
public string Password(string protocol)
101106
{
102-
return GetSettings(protocol).creds.Password;
107+
var proxy = GetProxy(protocol) as WebProxy;
108+
return proxy?.Credentials.GetCredential(proxy.Address, "Basic").Password ?? string.Empty;
103109
}
104110

105111
[ContextMethod("Сервер", "Server")]
106112
public string Server(string protocol)
107113
{
108-
return GetSettings(protocol).server;
114+
const UriComponents serverComponents = UriComponents.Scheme | UriComponents.Host | UriComponents.PathAndQuery;
115+
var proxy = GetProxy(protocol) as WebProxy;
116+
return proxy?.Address.GetComponents(serverComponents, UriFormat.UriEscaped) ?? string.Empty;
109117
}
110118

111119
[ContextMethod("Порт", "Password")]
112120
public int Port(string protocol)
113121
{
114-
return GetSettings(protocol).port;
122+
var proxy = GetProxy(protocol) as WebProxy;
123+
return proxy?.Address.Port ?? 0;
115124
}
116125

117126
[ContextMethod("Установить", "Set")]
118127
public void Set(string protocol, string server, int port = 0, string username = "", string password = "", bool useOSAuthentication = true)
119128
{
129+
protocol = protocol.ToLower();
120130
if(!ProtocolNameIsValid(protocol))
121131
throw RuntimeException.InvalidArgumentValue();
132+
133+
var builderServer = new UriBuilder(server);
134+
if (builderServer.Scheme.Equals(string.Empty))
135+
builderServer.Scheme = protocol;
136+
137+
if (port != 0)
138+
builderServer.Port = port;
139+
140+
var proxyCredentials = useOSAuthentication ? CredentialCache.DefaultNetworkCredentials :
141+
GetBasicCredential(builderServer.Uri, username, password);
122142

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;
143+
_proxies[protocol] = new WebProxy(builderServer.Uri, _bypassLocal,
144+
_bypassProxyOnAddresses?.Select(x => x.AsString()).ToArray() ?? new string[] {}, proxyCredentials);
132145
}
133146

134147
[ContextProperty("НеИспользоватьПроксиДляАдресов","BypassProxyOnAddresses")]
135148
public ArrayImpl BypassProxyList
136149
{
137-
get
138-
{
139-
return _bypassProxyOnAddresses;
140-
}
150+
get => _bypassProxyOnAddresses;
141151
set
142152
{
143153
_bypassProxyOnAddresses = value;
154+
var bypassList = _bypassProxyOnAddresses?.Select(x => x.AsString()).ToArray() ?? new string[] {};
155+
foreach (var kv in _proxies)
156+
if (kv.Value is WebProxy proxy)
157+
proxy.BypassList = bypassList;
144158
}
145159
}
146160

147161
[ContextProperty("НеИспользоватьПроксиДляЛокальныхАдресов", "BypassProxyOnLocal")]
148162
public bool BypassProxyOnLocal
149163
{
150-
get
151-
{
152-
return _bypassLocal;
153-
}
164+
get => _bypassLocal;
154165
set
155166
{
156167
_bypassLocal = value;
168+
foreach (var kv in _proxies)
169+
if (kv.Value is WebProxy proxy)
170+
proxy.BypassProxyOnLocal = _bypassLocal;
157171
}
158172
}
159173

160-
private ProxySettings GetSettings(string protocol)
161-
{
162-
if (!ProtocolNameIsValid(protocol))
163-
throw RuntimeException.InvalidArgumentValue();
164-
165-
return _proxies[protocol];
166-
}
167-
168174
private static bool ProtocolNameIsValid(string protocol)
169175
{
170-
return StringComparer.OrdinalIgnoreCase.Compare(protocol, PROTO_HTTP) == 0 || StringComparer.OrdinalIgnoreCase.Compare(protocol, PROTO_HTTPS) == 0;
176+
return Uri.UriSchemeHttp.Equals(protocol) || Uri.UriSchemeHttps.Equals(protocol);
171177
}
172178

173179
[ScriptConstructor(Name = "Формирование неинициализированного объекта")]

tests/http.os

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@
7979

8080
Процедура ТестДолжен_ПроверитьАвторизациюПрокси() Экспорт
8181

82-
Прокси = Новый ИнтернетПрокси();
82+
Прокси = Новый ИнтернетПрокси(Ложь);
8383

84-
Прокси.Установить("http","proxy.server.lan", 8080, "someuser", "somepassword");
84+
Прокси.Установить("http","proxy.server.lan", 8080, "someuser", "somepassword", Ложь);
8585

8686
юТест.ПроверитьРавенство("someuser",Прокси.Пользователь("http"));
8787
юТест.ПроверитьРавенство("somepassword",Прокси.Пароль("http"));

0 commit comments

Comments
 (0)