Skip to content

Commit 4927107

Browse files
committed
feat: Добавил разбор настроек прокси из переменных окружения
fix: Исправил basic авторизацию, если useOSAuthentication = false fix #1110
1 parent 8bf9fef commit 4927107

File tree

2 files changed

+79
-80
lines changed

2 files changed

+79
-80
lines changed

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

Lines changed: 78 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This Source Code Form is subject to the terms of the
1010
using System.Collections.Generic;
1111
using System.Linq;
1212
using System.Net;
13+
using System.Runtime.InteropServices;
1314

1415
namespace 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 = "Формирование неинициализированного объекта")]

src/ScriptEngine.HostedScript/ScriptEngine.HostedScript.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<ItemGroup>
1010
<PackageReference Include="DotNetZip" Version="1.13.3" />
1111
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
12+
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
1213
<ProjectReference Include="..\ScriptEngine\ScriptEngine.csproj" />
1314
</ItemGroup>
1415
<PropertyGroup>

0 commit comments

Comments
 (0)