Commit 8dad7fec authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

http: don't proxy loopback addresses

Fixes #1589

R=rsc
CC=golang-dev
https://golang.org/cl/4443053
parent 047e698c
......@@ -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)
}
}
}
......@@ -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
......
......@@ -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?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment