Skip to content

Commit

Permalink
proxy: move isLocalhost() impl HTTPProxy and do not rely on net.looku…
Browse files Browse the repository at this point in the history
…pStaticHost

Replace net.lookupStaticHost() with localhost aliases loaded on start.
  • Loading branch information
mmatczuk committed Sep 5, 2024
1 parent 90c526c commit 24f679e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 80 deletions.
25 changes: 21 additions & 4 deletions http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import (
"net"
"net/http"
"net/url"
"slices"
"sync"
"time"

"github.com/saucelabs/forwarder/hostsfile"
"github.com/saucelabs/forwarder/httplog"
"github.com/saucelabs/forwarder/internal/martian"
"github.com/saucelabs/forwarder/internal/martian/fifo"
Expand Down Expand Up @@ -145,6 +147,7 @@ type HTTPProxy struct {
proxy *martian.Proxy
mitmCACert *x509.Certificate
proxyFunc ProxyFunc
localhost []string

tlsConfig *tls.Config
listener net.Listener
Expand All @@ -164,6 +167,12 @@ func NewHTTPProxy(cfg *HTTPProxyConfig, pr PACResolver, cm *CredentialsMatcher,
}
}

lh, err := hostsfile.LocalhostAliases()
if err != nil {
return nil, fmt.Errorf("read localhost aliases: %w", err)
}
hp.localhost = append(hp.localhost, lh...)

l, err := hp.listen()
if err != nil {
return nil, err
Expand Down Expand Up @@ -209,6 +218,7 @@ func newHTTPProxy(cfg *HTTPProxyConfig, pr PACResolver, cm *CredentialsMatcher,
transport: rt,
log: log,
metrics: newHTTPProxyMetrics(cfg.PromRegistry, cfg.PromNamespace),
localhost: []string{"localhost", "0.0.0.0", "::"},
}

if err := hp.configureProxy(); err != nil {
Expand Down Expand Up @@ -405,7 +415,7 @@ func (hp *HTTPProxy) basicAuth(u *url.Userinfo) martian.RequestModifier {

func (hp *HTTPProxy) denyLocalhost() martian.RequestModifier {
return martian.RequestModifierFunc(func(req *http.Request) error {
if hp.isLocalhost(req) {
if hp.isLocalhost(req.URL.Hostname()) {
return ErrProxyLocalhost
}
return nil
Expand Down Expand Up @@ -440,15 +450,22 @@ func (hp *HTTPProxy) directLocalhost(fn ProxyFunc) ProxyFunc {
}

return func(req *http.Request) (*url.URL, error) {
if hp.isLocalhost(req) {
if hp.isLocalhost(req.URL.Hostname()) {
return nil, nil
}
return fn(req)
}
}

func (hp *HTTPProxy) isLocalhost(req *http.Request) bool {
return isLocalhost(req.URL.Hostname())
func (hp *HTTPProxy) isLocalhost(host string) bool {
if slices.Contains(hp.localhost, host) {
return true
}
if ip := net.ParseIP(host); ip != nil && ip.IsLoopback() {
return true
}

return false
}

func (hp *HTTPProxy) setBasicAuth(req *http.Request) error {
Expand Down
34 changes: 34 additions & 0 deletions http_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,37 @@ func TestNopDialer(t *testing.T) {
t.Fatalf("expected %v, got %v", nopDialerErr, err)
}
}

func TestIsLocalhost(t *testing.T) {
cfg := DefaultHTTPProxyConfig()
p, err := NewHTTPProxy(cfg, nil, nil, nil, stdlog.Default())
if err != nil {
t.Fatal(err)
}

tests := []struct {
host string
localhost bool
}{
{"127.0.0.1", true},
{"127.10.20.30", true},
{"localhost", true},
{"0.0.0.0", true},

{"notlocalhost", false},
{"broadcasthost", false},

{"::1", true},
{"::", true},

{"::10", false},
{"2001:0db8:85a3:0000:0000:8a2e:0370:7334", false},
}

for i := range tests {
tc := tests[i]
if lh := p.isLocalhost(tc.host); lh != tc.localhost {
t.Errorf("isLocalhost(%q) = %v; want %v", tc.host, lh, tc.localhost)
}
}
}
37 changes: 0 additions & 37 deletions resolver.go

This file was deleted.

39 changes: 0 additions & 39 deletions resolver_test.go

This file was deleted.

0 comments on commit 24f679e

Please sign in to comment.