Skip to content

Commit

Permalink
check for http_proxy & https_proxy env-vars
Browse files Browse the repository at this point in the history
this brings us in line with many other AWS SDKs which check for
these environment variables to modify client behavior. it does not
change behavior if you've already been setting your web proxy
explicitly, or in properties (the same as the java (and other) sdks).

we do introduce this with two new methods in ClientConfig to not break
any existing callers using the methods that are public. while all of our
callers have been updated to properly check web proxy, and then if
that's unset check the protocol being used and optionally call
`GetHttpProxy`/`GetHttpsProxy` as needed. If we're okay with breaking
ever IT MAY be worthwhile to break `GetWebProxy` by taking in the
protocol, and then just having the one method to prevent any accidental
mis-use, and to ensure everyone is using those environment variables.

it's also important to note:
<dotnet/runtime#31113> meaning a user will
just get an error if they try to proxy to something that is using
`HTTPS`. i figured just letting it error on construction is probably
the 'safest' option. letting the user know that their setting isn't
being respected, as opposed to just silently 'ignoring' it. this is
also a decision we might want to change.
  • Loading branch information
Mythra committed Jul 2, 2023
1 parent 2f0f8cd commit e04c5cd
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 11 deletions.
Expand Up @@ -474,6 +474,14 @@ public virtual void ConfigureRequest(IRequestContext requestContext)
requestContext.Metrics.AddProperty(Metric.ProxyPort, requestContext.ClientConfig.ProxyPort);
_request.Proxy = proxy;
}
else if (_request.RequestUri.Scheme == Uri.UriSchemeHttp)
{
_request.Proxy = requestContext.ClientConfig.GetHttpProxy();
}
else if (_request.RequestUri.Scheme == Uri.UriSchemeHttps)
{
_request.Proxy = requestContext.ClientConfig.GetHttpsProxy();
}

// Set service point properties.
_request.ServicePoint.ConnectionLimit = clientConfig.ConnectionLimit;
Expand Down
Expand Up @@ -270,7 +270,11 @@ private static HttpClient CreateManagedHttpClient(IClientConfig clientConfig)
}

try
{
{
// HTTP Client will automatically read `HTTP_PROXY`,
// and `HTTPS_PROXY`. So we let it use those variables, since
// we don't know at client construction time whether they're
// using HTTP or HTTPS.
var proxy = clientConfig.GetWebProxy();
if (proxy != null)
{
Expand Down
28 changes: 28 additions & 0 deletions sdk/src/Core/Amazon.Runtime/_bcl/ClientConfig.cs
Expand Up @@ -133,6 +133,34 @@ public WebProxy GetWebProxy()
return proxy;
}

/// <summary>
/// Returns a WebProxy instance to use for HTTPS connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
public WebProxy GetHttpsProxy()
{
var httpsProxy = Environment.GetEnvironmentVariable("https_proxy");
if (!string.IsNullOrEmpty(httpsProxy))
{
return new WebProxy(httpsProxy);
}
return null;
}

/// <summary>
/// Returns a WebProxy instance to use for HTTP connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
public WebProxy GetHttpProxy()
{
var httpProxy = Environment.GetEnvironmentVariable("http_proxy");
if (!string.IsNullOrEmpty(httpProxy))
{
return new WebProxy(httpProxy);
}
return null;
}

/// <summary>
/// Unpacks the host, port and any credentials info into the instance's
/// proxy-related fields.
Expand Down
11 changes: 11 additions & 0 deletions sdk/src/Core/Amazon.Runtime/_bcl/IClientConfig.bcl.cs
Expand Up @@ -70,5 +70,16 @@ public partial interface IClientConfig
/// </summary>
WebProxy GetWebProxy();

/// <summary>
/// Returns a WebProxy instance to use for HTTPS connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
WebProxy GetHttpsProxy();

/// <summary>
/// Returns a WebProxy instance to use for HTTP connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
WebProxy GetHttpProxy();
}
}
28 changes: 28 additions & 0 deletions sdk/src/Core/Amazon.Runtime/_netstandard/ClientConfig.cs
Expand Up @@ -46,6 +46,34 @@ public IWebProxy GetWebProxy()
return proxy;
}

/// <summary>
/// Returns a WebProxy instance to use for HTTPS connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
public IWebProxy GetHttpsProxy()
{
var httpsProxy = Environment.GetEnvironmentVariable("https_proxy");
if (!string.IsNullOrEmpty(httpsProxy))
{
return new Amazon.Runtime.Internal.Util.WebProxy(httpsProxy);
}
return proxy;
}

/// <summary>
/// Returns a WebProxy instance to use for HTTP connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
public IWebProxy GetHttpProxy()
{
var httpProxy = Environment.GetEnvironmentVariable("http_proxy");
if (!string.IsNullOrEmpty(httpProxy))
{
return new Amazon.Runtime.Internal.Util.WebProxy(httpProxy);
}
return proxy;
}

/// <summary>
/// Unpacks the host, port and any credentials info into the instance's
/// proxy-related fields.
Expand Down
12 changes: 12 additions & 0 deletions sdk/src/Core/Amazon.Runtime/_netstandard/IClientConfig.cs
Expand Up @@ -43,6 +43,18 @@ public partial interface IClientConfig
/// </summary>
IWebProxy GetWebProxy();

/// <summary>
/// Returns a WebProxy instance to use for HTTPS connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
IWebProxy GetHttpsProxy();

/// <summary>
/// Returns a WebProxy instance to use for HTTP connections if an
/// explicit web proxy hasn't been configured.
/// </summary>
IWebProxy GetHttpProxy();

/// <summary>
/// HttpClientFactory used to create new HttpClients.
/// If null, an HttpClient will be created by the SDK.
Expand Down
24 changes: 22 additions & 2 deletions sdk/src/Services/EC2/Custom/Util/_async/ImageUtilities.async.cs
Expand Up @@ -82,10 +82,17 @@ private static async Task LoadDefinitionsFromWebAsync(AmazonEC2Config ec2Config)
if (ImageDefinitionsLoaded)
return;
}
const string httpPrefix = "http://";
const string httpsPrefix = "https://";

IWebProxy webProxy = null;
if (ec2Config != null)
IWebProxy httpProxy = null;
IWebProxy httpsProxy = null;
if (ec2Config != null) {
webProxy = ec2Config.GetWebProxy();
httpProxy = ec2Config.GetHttpProxy();
httpsProxy = ec2Config.GetHttpsProxy();
}

int retries = 0;
while (retries < MAX_DOWNLOAD_RETRIES)
Expand All @@ -95,9 +102,22 @@ private static async Task LoadDefinitionsFromWebAsync(AmazonEC2Config ec2Config)
HttpWebResponse response = null;
foreach (var location in DownloadLocations)
{
var useProxy = webProxy;
if (useProxy == null)
{
if (location.StartsWith(httpPrefix))
{
useProxy = httpProxy;
}
else if (location.StartsWith(httpsPrefix))
{
useProxy = httpsProxy;
}
}

try
{
response = await DownloadControlFileAsync(location, webProxy).ConfigureAwait(false);
response = await DownloadControlFileAsync(location, useProxy).ConfigureAwait(false);
if (response != null)
break;
}
Expand Down
24 changes: 22 additions & 2 deletions sdk/src/Services/EC2/Custom/Util/_bcl/ImageUtilities.bcl.cs
Expand Up @@ -82,10 +82,17 @@ private static void LoadDefinitionsFromWeb(AmazonEC2Config ec2Config)
if (ImageDefinitionsLoaded)
return;
}
const string httpPrefix = "http://";
const string httpsPrefix = "https://";

IWebProxy webProxy = null;
if (ec2Config != null)
IWebProxy httpProxy = null;
IWebProxy httpsProxy = null;
if (ec2Config != null) {
webProxy = ec2Config.GetWebProxy();
httpProxy = ec2Config.GetHttpProxy();
httpsProxy = ec2Config.GetHttpsProxy();
}

int retries = 0;
while (retries < MAX_DOWNLOAD_RETRIES)
Expand All @@ -95,9 +102,22 @@ private static void LoadDefinitionsFromWeb(AmazonEC2Config ec2Config)
HttpWebResponse response = null;
foreach (var location in DownloadLocations)
{
var useProxy = webProxy;
if (useProxy == null)
{
if (location.StartsWith(httpPrefix))
{
useProxy = httpProxy;
}
else if (location.StartsWith(httpsPrefix))
{
useProxy = httpsProxy;
}
}

try
{
response = DownloadControlFile(location, webProxy);
response = DownloadControlFile(location, useProxy);
if (response != null)
break;
}
Expand Down
11 changes: 11 additions & 0 deletions sdk/src/Services/S3/Custom/AmazonS3Client.Extensions.cs
Expand Up @@ -361,6 +361,17 @@ internal void ConfigureProxy(HttpWebRequest httpRequest)
{
httpRequest.Proxy.Credentials = Config.ProxyCredentials;
}
if (httpRequest.Proxy == null)
{
if (httpRequest.RequestUri.Scheme == Uri.UriSchemeHttp)
{
httpRequest.Proxy = Config.GetHttpProxy();
}
else if (httpRequest.RequestUri.Scheme == Uri.UriSchemeHttps)
{
httpRequest.Proxy = Config.GetHttpsProxy();
}
}
}


Expand Down
14 changes: 9 additions & 5 deletions sdk/src/Services/S3/Custom/Util/AmazonS3HttpUtil.cs
Expand Up @@ -112,15 +112,19 @@ private static GetHeadResponse HandleWebException(string header, WebException we

private static void SetProxyIfAvailableAndConfigured(IClientConfig config, HttpWebRequest httpWebRequest)
{
var proxy = GetProxyIfAvailableAndConfigured(config);
var proxy = config.GetWebProxy();
if (proxy != null)
{
httpWebRequest.Proxy = proxy;
}
}
private static IWebProxy GetProxyIfAvailableAndConfigured(IClientConfig config)
{
return config.GetWebProxy();
else if (httpWebRequest.RequestUri.Scheme == Uri.UriSchemeHttp)
{
httpWebRequest.Proxy = config.GetHttpProxy();
}
else if (httpWebRequest.RequestUri.Scheme == Uri.UriSchemeHttps)
{
httpWebRequest.Proxy = config.GetHttpsProxy();
}
}
}
}
Expand Up @@ -40,11 +40,25 @@ public partial class AmazonSecurityTokenServiceClient : AmazonServiceClient, IAm
TimeSpan credentialDuration,
ICredentials userCredential)
{
const string httpPrefix = "http://";
const string httpsPrefix = "https://";
SAMLAssertion assertion;

try
{
var authController = new SAMLAuthenticationController(Config.GetWebProxy());
var proxy = Config.GetWebProxy();
if (proxy == null)
{
if (endpoint.StartsWith(httpPrefix))
{
proxy = Config.GetHttpProxy();
}
else if (endpoint.StartsWith(httpsPrefix))
{
proxy = Config.GetHttpsProxy();
}
}
var authController = new SAMLAuthenticationController(proxy);
assertion = authController.GetSAMLAssertion(endpoint, userCredential, authenticationType);
}
catch (Exception e)
Expand Down

0 comments on commit e04c5cd

Please sign in to comment.