From a7d3de12cc3046bfae19cd1101393f6e792f92ec Mon Sep 17 00:00:00 2001 From: Youhei Sakurai Date: Sat, 30 Sep 2023 02:21:06 +0900 Subject: [PATCH 1/4] Make test output honor output.logstash.proxy_url Relates elastic/beats#24751 --- transport/client.go | 30 +++++++++++++++++++++++++----- transport/proxy.go | 13 +++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/transport/client.go b/transport/client.go index 5e97ff1e..e2692858 100644 --- a/transport/client.go +++ b/transport/client.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "net" + "net/url" "sync" "time" @@ -215,9 +216,25 @@ func (c *Client) handleError(err error) error { func (c *Client) Test(d testing.Driver) { d.Run("logstash: "+c.host, func(d testing.Driver) { + if c.config.Proxy.URL != "" { + d.Run("proxy", func(d testing.Driver) { + url, err1 := url.Parse(c.config.Proxy.URL) + d.Fatal("parse url", err1) + dialer := TestNetDialer(d, c.config.Timeout) + _, err2 := dialer.Dial("tcp", url.Host) + d.Fatal("dial up", err2) + }) + } + d.Run("connection", func(d testing.Driver) { - netDialer := TestNetDialer(d, c.config.Timeout) - _, err := netDialer.Dial("tcp", c.host) + var dialer Dialer + if c.config.Proxy.URL == "" { + dialer = TestNetDialer(d, c.config.Timeout) + } else { + dialer = NetDialer(c.config.Timeout) + dialer = TestProxyDialer(d, dialer, c.config.Proxy, c.config.Timeout) + } + _, err := dialer.Dial("tcp", c.host) d.Fatal("dial up", err) }) @@ -225,9 +242,12 @@ func (c *Client) Test(d testing.Driver) { d.Warn("TLS", "secure connection disabled") } else { d.Run("TLS", func(d testing.Driver) { - netDialer := NetDialer(c.config.Timeout) - tlsDialer := TestTLSDialer(d, netDialer, c.config.TLS, c.config.Timeout) - _, err := tlsDialer.Dial("tcp", c.host) + dialer := NetDialer(c.config.Timeout) + if c.config.Proxy.URL != "" { + dialer = TestProxyDialer(d, dialer, c.config.Proxy, c.config.Timeout) + } + dialer = TestTLSDialer(d, dialer, c.config.TLS, c.config.Timeout) + _, err := dialer.Dial("tcp", c.host) d.Fatal("dial up", err) }) } diff --git a/transport/proxy.go b/transport/proxy.go index 3c3dbf65..d9bcaeb8 100644 --- a/transport/proxy.go +++ b/transport/proxy.go @@ -20,10 +20,12 @@ package transport import ( "net" "net/url" + "time" "golang.org/x/net/proxy" "github.com/elastic/elastic-agent-libs/logp" + "github.com/elastic/elastic-agent-libs/testing" ) // ProxyConfig holds the configuration information required to proxy @@ -97,3 +99,14 @@ func ProxyDialer(log *logp.Logger, config *ProxyConfig, forward Dialer) (Dialer, return DialWith(dialer, network, host, addresses, port) }), nil } + +func TestProxyDialer( + d testing.Driver, + forward Dialer, + config *ProxyConfig, + timeout time.Duration, +) Dialer { + dialer, err := ProxyDialer(logp.L(), config, forward) + d.Fatal("proxy", err) + return dialer +} From aa8396f3df5c22b48606e89b821c4e59fff1e45d Mon Sep 17 00:00:00 2001 From: Youhei Sakurai Date: Sat, 30 Sep 2023 22:01:19 +0900 Subject: [PATCH 2/4] Remove an unused argument on TestProxyDialer --- transport/client.go | 4 ++-- transport/proxy.go | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/transport/client.go b/transport/client.go index e2692858..206e36f7 100644 --- a/transport/client.go +++ b/transport/client.go @@ -232,7 +232,7 @@ func (c *Client) Test(d testing.Driver) { dialer = TestNetDialer(d, c.config.Timeout) } else { dialer = NetDialer(c.config.Timeout) - dialer = TestProxyDialer(d, dialer, c.config.Proxy, c.config.Timeout) + dialer = TestProxyDialer(d, dialer, c.config.Proxy) } _, err := dialer.Dial("tcp", c.host) d.Fatal("dial up", err) @@ -244,7 +244,7 @@ func (c *Client) Test(d testing.Driver) { d.Run("TLS", func(d testing.Driver) { dialer := NetDialer(c.config.Timeout) if c.config.Proxy.URL != "" { - dialer = TestProxyDialer(d, dialer, c.config.Proxy, c.config.Timeout) + dialer = TestProxyDialer(d, dialer, c.config.Proxy) } dialer = TestTLSDialer(d, dialer, c.config.TLS, c.config.Timeout) _, err := dialer.Dial("tcp", c.host) diff --git a/transport/proxy.go b/transport/proxy.go index d9bcaeb8..ddf51562 100644 --- a/transport/proxy.go +++ b/transport/proxy.go @@ -20,7 +20,6 @@ package transport import ( "net" "net/url" - "time" "golang.org/x/net/proxy" @@ -104,7 +103,6 @@ func TestProxyDialer( d testing.Driver, forward Dialer, config *ProxyConfig, - timeout time.Duration, ) Dialer { dialer, err := ProxyDialer(logp.L(), config, forward) d.Fatal("proxy", err) From f8bc962cca8a3e9cb7dacc9d2ecb2f449ce9b04d Mon Sep 17 00:00:00 2001 From: Youhei Sakurai Date: Mon, 2 Oct 2023 17:42:45 +0900 Subject: [PATCH 3/4] Add code for elastic/beats#36715 --- transport/httpcommon/proxy.go | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/transport/httpcommon/proxy.go b/transport/httpcommon/proxy.go index 9779d02f..bd7c655f 100644 --- a/transport/httpcommon/proxy.go +++ b/transport/httpcommon/proxy.go @@ -18,10 +18,16 @@ package httpcommon import ( + "bufio" + "encoding/base64" + "fmt" + "net" "net/http" "net/url" "github.com/elastic/elastic-agent-libs/config" + "github.com/elastic/elastic-agent-libs/transport" + "golang.org/x/net/proxy" ) // HTTPClientProxySettings provides common HTTP proxy setup support. @@ -104,3 +110,54 @@ func (settings *HTTPClientProxySettings) ProxyFunc() func(*http.Request) (*url.U return http.ProxyURL(settings.URL.URI()) } + +// ProxyDialer is a dialer that can be registered to golang.org/x/net/proxy +func (settings *HTTPClientProxySettings) ProxyDialer(_ *url.URL, forward proxy.Dialer) (proxy.Dialer, error) { + return transport.DialerFunc(func(_, address string) (net.Conn, error) { + + // Headers given to the CONNECT request + hdr := settings.Headers.Headers() + if settings.URL.User != nil { + username := settings.URL.User.Username() + password, _ := settings.URL.User.Password() + if len(hdr) == 0 { + hdr = http.Header{} + } + hdr.Add("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password))) + } + + req := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: address}, + Host: address, + Header: hdr, + } + + // Dial the proxy host + c, err := forward.Dial("tcp", settings.URL.Host) + if err != nil { + return nil, err + } + + // Write the CONNECT request + err = req.Write(c) + if err != nil { + c.Close() + return nil, err + } + + res, err := http.ReadResponse(bufio.NewReader(c), req) + if err != nil { + c.Close() + return nil, err + } + res.Body.Close() + + if res.StatusCode != http.StatusOK { + c.Close() + return nil, fmt.Errorf("proxy server returned status code %d", res.StatusCode) + } + + return c, nil + }), nil +} From 89e6f4b546b9d7579546294c51dcb31a6573da2a Mon Sep 17 00:00:00 2001 From: Youhei Sakurai Date: Tue, 24 Oct 2023 22:22:07 +0900 Subject: [PATCH 4/4] Isolate the fix from another --- transport/client.go | 4 +-- transport/httpcommon/proxy.go | 57 ----------------------------------- transport/proxy.go | 2 +- 3 files changed, 3 insertions(+), 60 deletions(-) diff --git a/transport/client.go b/transport/client.go index 206e36f7..53f2daf7 100644 --- a/transport/client.go +++ b/transport/client.go @@ -232,7 +232,7 @@ func (c *Client) Test(d testing.Driver) { dialer = TestNetDialer(d, c.config.Timeout) } else { dialer = NetDialer(c.config.Timeout) - dialer = TestProxyDialer(d, dialer, c.config.Proxy) + dialer = testProxyDialer(d, dialer, c.config.Proxy) } _, err := dialer.Dial("tcp", c.host) d.Fatal("dial up", err) @@ -244,7 +244,7 @@ func (c *Client) Test(d testing.Driver) { d.Run("TLS", func(d testing.Driver) { dialer := NetDialer(c.config.Timeout) if c.config.Proxy.URL != "" { - dialer = TestProxyDialer(d, dialer, c.config.Proxy) + dialer = testProxyDialer(d, dialer, c.config.Proxy) } dialer = TestTLSDialer(d, dialer, c.config.TLS, c.config.Timeout) _, err := dialer.Dial("tcp", c.host) diff --git a/transport/httpcommon/proxy.go b/transport/httpcommon/proxy.go index bd7c655f..9779d02f 100644 --- a/transport/httpcommon/proxy.go +++ b/transport/httpcommon/proxy.go @@ -18,16 +18,10 @@ package httpcommon import ( - "bufio" - "encoding/base64" - "fmt" - "net" "net/http" "net/url" "github.com/elastic/elastic-agent-libs/config" - "github.com/elastic/elastic-agent-libs/transport" - "golang.org/x/net/proxy" ) // HTTPClientProxySettings provides common HTTP proxy setup support. @@ -110,54 +104,3 @@ func (settings *HTTPClientProxySettings) ProxyFunc() func(*http.Request) (*url.U return http.ProxyURL(settings.URL.URI()) } - -// ProxyDialer is a dialer that can be registered to golang.org/x/net/proxy -func (settings *HTTPClientProxySettings) ProxyDialer(_ *url.URL, forward proxy.Dialer) (proxy.Dialer, error) { - return transport.DialerFunc(func(_, address string) (net.Conn, error) { - - // Headers given to the CONNECT request - hdr := settings.Headers.Headers() - if settings.URL.User != nil { - username := settings.URL.User.Username() - password, _ := settings.URL.User.Password() - if len(hdr) == 0 { - hdr = http.Header{} - } - hdr.Add("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password))) - } - - req := &http.Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: address}, - Host: address, - Header: hdr, - } - - // Dial the proxy host - c, err := forward.Dial("tcp", settings.URL.Host) - if err != nil { - return nil, err - } - - // Write the CONNECT request - err = req.Write(c) - if err != nil { - c.Close() - return nil, err - } - - res, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - c.Close() - return nil, err - } - res.Body.Close() - - if res.StatusCode != http.StatusOK { - c.Close() - return nil, fmt.Errorf("proxy server returned status code %d", res.StatusCode) - } - - return c, nil - }), nil -} diff --git a/transport/proxy.go b/transport/proxy.go index ddf51562..c1fcfd6a 100644 --- a/transport/proxy.go +++ b/transport/proxy.go @@ -99,7 +99,7 @@ func ProxyDialer(log *logp.Logger, config *ProxyConfig, forward Dialer) (Dialer, }), nil } -func TestProxyDialer( +func testProxyDialer( d testing.Driver, forward Dialer, config *ProxyConfig,