你正在使用哪个版本的Go( go version
)?
$ go version
go version go1.18.2 linux/amd64
这个问题在最新版本中是否会重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ubuntu/.cache/go-build"
GOENV="/home/ubuntu/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ubuntu/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ubuntu/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/ubuntu/.local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/ubuntu/.local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/ubuntu/hello/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build736401068=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
我们模拟了一个行为,其中CoreDNS健康插件通过http_proxy向 http://:8080/health
发送http请求,该请求由健康插件本身监听。我们发现,如果我们指定 http://127.0.0.1:8080/
,它将无法连接到代理,但只有在我们指定 http://:8080/health
时,它才会始终连接到代理。
以下示例代码使用了net/http的默认传输方式,模仿了CoreDNS健康插件中的过载函数,在运行之前配置 export http_proxy=http://127.0.0.1:8000
:
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
timeout := time.Duration(3 * time.Second)
client := http.Client{
Timeout: timeout,
}
// url := "http://127.0.0.1:8080/health" // not using proxy
url := "http://:8080/health" // using proxy
resp, err := client.Get(url)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("succeed")
resp.Body.Close()
}
你期望看到什么?
Get "http://:8080/health": dial tcp 127.0.0.1:8080: connect: connection refused
应该显示,因为它不应该到达代理
你看到了什么?
Get "http://:8080/health": proxyconnect tcp: dial tcp 127.0.0.1:8000: connect: connection refused
请注意, useProxy 函数专门检查 "localhost" 和环回地址,如果没有提供主机名,是否也应该使用代理是有意义的?
另请参阅: #1589 和 #28866 ,请注意,在这种情况下,无法使用no_proxy来豁免代理的使用,因为no_proxy跳过了空字符串。
2条答案
按热度按时间mfpqipee1#
CC @neild
o4tp2gmn2#
我很惊讶我们愿意在URL中使用空主机名发起请求。这是不幸的。
由于改变这种行为是危险的(这里有一个证明的例子,有人依赖它),don't-proxy-localhost检查也应该查找空字符串。可能
0.0.0.0
和[::]
也需要检查,因为net.Dial
也把它们当作环回地址处理。