From 8ef48200b4fb3f6275e415dce13986d9a646ad4f Mon Sep 17 00:00:00 2001 From: Ferenc Hammerl <31069338+fhammerl@users.noreply.github.com> Date: Mon, 6 Mar 2023 11:01:45 +0100 Subject: [PATCH] Bypass all proxies for all hosts if `no_proxy='*'` is set (#2395) * Bypass top level domain even if no_proxy specified it with leading '.' E.g. no_proxy='.github.com' will now bypass github.com. * Bypass proxy on all hosts when no_proxy is * (wildcard) * Undo '.' stripping * Simplify unit tests * Respect wildcard even if it's one of many no_proxy items --- src/Runner.Sdk/RunnerWebProxy.cs | 6 ++- src/Test/L0/RunnerWebProxyL0.cs | 72 +++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/Runner.Sdk/RunnerWebProxy.cs b/src/Runner.Sdk/RunnerWebProxy.cs index 516b1dcec..ccf83f6fa 100644 --- a/src/Runner.Sdk/RunnerWebProxy.cs +++ b/src/Runner.Sdk/RunnerWebProxy.cs @@ -164,7 +164,6 @@ namespace GitHub.Runner.Sdk { continue; } - _noProxyList.Add(noProxyInfo); } } @@ -207,6 +206,11 @@ namespace GitHub.Runner.Sdk { foreach (var noProxy in _noProxyList) { + // bypass on wildcard no_proxy + if (string.Equals(noProxy.Host, "*", StringComparison.OrdinalIgnoreCase)) + { + return true; + } var matchHost = false; var matchPort = false; diff --git a/src/Test/L0/RunnerWebProxyL0.cs b/src/Test/L0/RunnerWebProxyL0.cs index 649f06197..dacc63731 100644 --- a/src/Test/L0/RunnerWebProxyL0.cs +++ b/src/Test/L0/RunnerWebProxyL0.cs @@ -351,7 +351,7 @@ namespace GitHub.Runner.Common.Tests Assert.False(proxy.IsBypassed(new Uri("https://actions.com"))); Assert.False(proxy.IsBypassed(new Uri("https://ggithub.com"))); Assert.False(proxy.IsBypassed(new Uri("https://github.comm"))); - Assert.False(proxy.IsBypassed(new Uri("https://google.com"))); + Assert.False(proxy.IsBypassed(new Uri("https://google.com"))); // no_proxy has '.google.com', specifying only subdomains bypass Assert.False(proxy.IsBypassed(new Uri("https://example.com"))); Assert.False(proxy.IsBypassed(new Uri("http://example.com:333"))); Assert.False(proxy.IsBypassed(new Uri("http://192.168.0.123:123"))); @@ -374,6 +374,76 @@ namespace GitHub.Runner.Common.Tests CleanProxyEnv(); } } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void BypassAllOnWildcardNoProxy() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "example.com, * , example2.com"); + var proxy = new RunnerWebProxy(); + + Assert.True(proxy.IsBypassed(new Uri("http://actions.com"))); + Assert.True(proxy.IsBypassed(new Uri("http://localhost"))); + Assert.True(proxy.IsBypassed(new Uri("http://127.0.0.1:8080"))); + Assert.True(proxy.IsBypassed(new Uri("https://actions.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://localhost"))); + Assert.True(proxy.IsBypassed(new Uri("https://127.0.0.1:8080"))); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void IgnoreWildcardInNoProxySubdomain() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "*.example.com"); + var proxy = new RunnerWebProxy(); + + Assert.False(proxy.IsBypassed(new Uri("http://sub.example.com"))); + Assert.False(proxy.IsBypassed(new Uri("http://example.com"))); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WildcardNoProxyWorksWhenOtherNoProxyAreAround() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "example.com,*,example2.com"); + var proxy = new RunnerWebProxy(); + + Assert.True(proxy.IsBypassed(new Uri("http://actions.com"))); + Assert.True(proxy.IsBypassed(new Uri("http://localhost"))); + Assert.True(proxy.IsBypassed(new Uri("http://127.0.0.1:8080"))); + Assert.True(proxy.IsBypassed(new Uri("https://actions.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://localhost"))); + Assert.True(proxy.IsBypassed(new Uri("https://127.0.0.1:8080"))); + } + finally + { + CleanProxyEnv(); + } + } [Fact] [Trait("Level", "L0")]