Skip to content

Commit c70609e

Browse files
committed
[SREP-1559] check that when used, proxy url starts with http and do proxy hostname dns lookup to confirm connectivity
1 parent bbcffa9 commit c70609e

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

pkg/cli/config/config.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"context"
55
"fmt"
6+
"net"
67
"net/http"
78
"net/url"
89
"os"
@@ -222,6 +223,8 @@ func GetBackplaneConfiguration() (bpConfig BackplaneConfiguration, err error) {
222223
return bpConfig, nil
223224
}
224225

226+
var lookupHost = net.LookupHost
227+
225228
var testProxy = func(ctx context.Context, testURL string, proxyURL url.URL) error {
226229
// Try call the test URL via the proxy
227230
client := &http.Client{
@@ -410,6 +413,15 @@ func (config *BackplaneConfiguration) testHTTPRequestToBackplaneAPI() (bool, err
410413
if err != nil {
411414
return false, err
412415
}
416+
scheme := proxyURL.Scheme
417+
if scheme != "http" && scheme != "https" {
418+
return false, fmt.Errorf("proxy URL scheme must be http or https, got: %s", scheme)
419+
}
420+
hostname := proxyURL.Hostname()
421+
_, err = lookupHost(hostname)
422+
if err != nil {
423+
return false, fmt.Errorf("DNS lookup failed for proxy hostname '%s': %v (check network connectivity or VPN if required)", hostname, err)
424+
}
413425
http.DefaultTransport = &http.Transport{Proxy: http.ProxyURL(proxyURL)}
414426
}
415427

pkg/cli/config/config_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http/httptest"
88
"net/url"
99
"os"
10+
"strings"
1011
"testing"
1112

1213
"github.com/spf13/viper"
@@ -85,6 +86,89 @@ func TestGetBackplaneConnection(t *testing.T) {
8586
t.Failed()
8687
}
8788
})
89+
90+
t.Run("should pass for valid http proxy URL", func(t *testing.T) {
91+
proxyURL := "http://www.example.com"
92+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
93+
_, err := config.testHTTPRequestToBackplaneAPI()
94+
95+
// Should not get scheme validation error (DNS lookup error is expected)
96+
if err != nil && strings.Contains(err.Error(), "proxy URL scheme must be http or https") {
97+
t.Errorf("unexpected scheme validation error: %v", err)
98+
}
99+
})
100+
101+
t.Run("should pass for valid https proxy URL", func(t *testing.T) {
102+
proxyURL := "https://www.example.com"
103+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
104+
_, err := config.testHTTPRequestToBackplaneAPI()
105+
106+
// Should not get scheme validation error (DNS lookup error is expected)
107+
if err != nil && strings.Contains(err.Error(), "proxy URL scheme must be http or https") {
108+
t.Errorf("unexpected scheme validation error: %v", err)
109+
}
110+
})
111+
112+
t.Run("should fail for proxy URL without scheme", func(t *testing.T) {
113+
proxyURL := "www.example.com"
114+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
115+
_, err := config.testHTTPRequestToBackplaneAPI()
116+
117+
if err == nil {
118+
t.Errorf("expected error but got none")
119+
} else if !strings.Contains(err.Error(), "proxy URL scheme must be http or https, got:") {
120+
t.Errorf("expected scheme validation error, got: %s", err.Error())
121+
}
122+
})
123+
124+
t.Run("should fail for ftp proxy URL", func(t *testing.T) {
125+
proxyURL := "ftp://www.example.com"
126+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
127+
_, err := config.testHTTPRequestToBackplaneAPI()
128+
129+
if err == nil {
130+
t.Errorf("expected error but got none")
131+
} else if !strings.Contains(err.Error(), "proxy URL scheme must be http or https, got: ftp") {
132+
t.Errorf("expected scheme validation error for ftp, got: %s", err.Error())
133+
}
134+
})
135+
136+
t.Run("should fail on DNS lookup error", func(t *testing.T) {
137+
// Mock DNS lookup to return an error
138+
originalLookupHost := lookupHost
139+
lookupHost = func(hostname string) ([]string, error) {
140+
return nil, fmt.Errorf("DNS resolution failed")
141+
}
142+
defer func() { lookupHost = originalLookupHost }()
143+
144+
proxyURL := "https://proxy.example.com"
145+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
146+
_, err := config.testHTTPRequestToBackplaneAPI()
147+
148+
if err == nil {
149+
t.Errorf("expected DNS lookup error but got none")
150+
} else if !strings.Contains(err.Error(), "DNS lookup failed for proxy hostname") {
151+
t.Errorf("expected DNS lookup error, got: %s", err.Error())
152+
}
153+
})
154+
155+
t.Run("should pass on successful DNS lookup", func(t *testing.T) {
156+
// Mock DNS lookup to succeed
157+
originalLookupHost := lookupHost
158+
lookupHost = func(hostname string) ([]string, error) {
159+
return []string{"192.168.1.1"}, nil
160+
}
161+
defer func() { lookupHost = originalLookupHost }()
162+
163+
proxyURL := "https://proxy.example.com"
164+
config := BackplaneConfiguration{URL: "https://api.example.com", ProxyURL: &proxyURL}
165+
_, err := config.testHTTPRequestToBackplaneAPI()
166+
167+
// Should not get DNS lookup error (HTTP request error is expected)
168+
if err != nil && strings.Contains(err.Error(), "DNS lookup failed for proxy hostname") {
169+
t.Errorf("unexpected DNS lookup error: %v", err)
170+
}
171+
})
88172
}
89173

90174
func TestBackplaneConfiguration_getFirstWorkingProxyURL(t *testing.T) {

0 commit comments

Comments
 (0)