]> Cypherpunks repositories - gostls13.git/commitdiff
http: don't proxy loopback addresses
authorBrad Fitzpatrick <bradfitz@golang.org>
Wed, 20 Apr 2011 20:53:34 +0000 (13:53 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 20 Apr 2011 20:53:34 +0000 (13:53 -0700)
Fixes #1589

R=rsc
CC=golang-dev
https://golang.org/cl/4443053

src/pkg/http/proxy_test.go
src/pkg/http/transport.go
src/pkg/net/ip.go

index 7050ef5ed063d96fc15fe957c72a2020580668a7..308bf44b48aec78f161592c0c050976cd97e76a7 100644 (file)
@@ -16,9 +16,15 @@ var UseProxyTests = []struct {
        host  string
        match bool
 }{
-       {"localhost", false},      // match completely
+       // Never proxy localhost:
+       {"localhost:80", false},
+       {"127.0.0.1", false},
+       {"127.0.0.2", false},
+       {"[::1]", false},
+       {"[::2]", true}, // not a loopback address
+
        {"barbaz.net", false},     // match as .barbaz.net
-       {"foobar.com:443", false}, // have a port but match 
+       {"foobar.com", false},     // have a port but match 
        {"foofoobar.com", true},   // not match as a part of foobar.com
        {"baz.com", true},         // not match as a part of barbaz.com
        {"localhost.net", true},   // not match as suffix of address
@@ -29,19 +35,16 @@ var UseProxyTests = []struct {
 
 func TestUseProxy(t *testing.T) {
        oldenv := os.Getenv("NO_PROXY")
-       no_proxy := "foobar.com, .barbaz.net   , localhost"
-       os.Setenv("NO_PROXY", no_proxy)
        defer os.Setenv("NO_PROXY", oldenv)
 
+       no_proxy := "foobar.com, .barbaz.net"
+       os.Setenv("NO_PROXY", no_proxy)
+
        tr := &Transport{}
 
        for _, test := range UseProxyTests {
-               if tr.useProxy(test.host) != test.match {
-                       if test.match {
-                               t.Errorf("useProxy(%v) = %v, want %v", test.host, !test.match, test.match)
-                       } else {
-                               t.Errorf("not expected: '%s' shouldn't match as '%s'", test.host, no_proxy)
-                       }
+               if tr.useProxy(test.host+":80") != test.match {
+                       t.Errorf("useProxy(%v) = %v, want %v", test.host, !test.match, test.match)
                }
        }
 }
index d87a64613c5f146598eccbebd295da94186671b6..6250880b158c6119d6ff9ea9323990a1522f74ad 100644 (file)
@@ -6,6 +6,7 @@ package http
 
 import (
        "bufio"
+       "bytes"
        "compress/gzip"
        "crypto/tls"
        "encoding/base64"
@@ -291,10 +292,28 @@ func (t *Transport) getConn(cm *connectMethod) (*persistConn, os.Error) {
 
 // useProxy returns true if requests to addr should use a proxy,
 // according to the NO_PROXY or no_proxy environment variable.
+// addr is always a canonicalAddr with a host and port.
 func (t *Transport) useProxy(addr string) bool {
        if len(addr) == 0 {
                return true
        }
+       host, _, err := net.SplitHostPort(addr)
+       if err != nil {
+               return false
+       }
+       if host == "localhost" {
+               return false
+       }
+       if ip := net.ParseIP(host); ip != nil {
+               if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
+                       // 127.0.0.0/8 loopback isn't proxied.
+                       return false
+               }
+               if bytes.Equal(ip, net.IPv6loopback) {
+                       return false
+               }
+       }
+
        no_proxy := t.getenvEitherCase("NO_PROXY")
        if no_proxy == "*" {
                return false
index 2429b10d9b354a3128c4acc6581bdf7de2f524fd..61b2c687e2fe28bbd28319e78ebd1f617f911ea3 100644 (file)
@@ -75,7 +75,8 @@ var (
 
 // Well-known IPv6 addresses
 var (
-       IPzero = make(IP, IPv6len) // all zeros
+       IPzero       = make(IP, IPv6len) // all zeros
+       IPv6loopback = IP([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
 )
 
 // Is p all zeros?