Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http/httptest: Server uses ipv4 instead of using both Ipv4 and Ipv6 #71178

Closed
bdollma-te opened this issue Jan 8, 2025 · 3 comments
Closed

Comments

@bdollma-te
Copy link

Go version

go version go1.21.0 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN='/auto/srg-sce-swinfra-usr/emb/users/bdollma/sdflow/scripts/../bin'
GOCACHE='/auto/srg-sce-swinfra-usr/emb/users/bdollma/go/cache'
GOENV='/users/bdollma/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/auto/srg-sce-swinfra-usr/emb/users/bdollma/sdflow/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/auto/srg-sce-swinfra-usr/emb/users/bdollma/sdflow/scripts/..'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/auto/srg-sce-swinfra-usr/emb/users/bdollma/go1.21.0'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/auto/srg-sce-swinfra-usr/emb/users/bdollma/go1.21.0/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK='/auto/srg-sce-swinfra-usr/emb/users/bdollma/sdflow/go.work'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1206231536=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Create a httptest.Server using the NewServer.

func TestIssue(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	}))
	defer srv.Close()

	u, err := url.Parse(srv.URL)
	require.NoError(t, err)
	port, err := strconv.Atoi(u.Port())
	require.NoError(t, err)
	url := fmt.Sprintf("http://localhost:%d", port)

	client := http.Client{}
	req, err := http.NewRequest(http.MethodPost, url, http.NoBody)
	require.NoError(t, err)
	req.Close = true
	resp, err := client.Do(req)
	require.NoError(t, err)
	require.Equal(t, http.StatusOK, resp.StatusCode)
}

Run the test:

go test -v . -run TestIssue -count 10000 -failfast
    http_server_test.go:280: 
                Error Trace:    ...
                Error:          Received unexpected error:
                                Post "http://localhost:44269": EOF
                Test:           TestIssue

What did you see happen?

After drilling down, the listener created for httptest.Server is IPv4 only:

l, err := net.Listen("tcp", "127.0.0.1:0")

and uses 127.0.0.1:0.

The test fails because at some point the client starts using IPv6. The server simply doesn't respond.

Screenshot 2025-01-08 at 17 18 25

What did you expect to see?

At least a better error. Simply returning EOF doesn't remotely help pinpoint the error.
You can argue that I should have used srv.URL instead of parsing the port and using localhost:port. However, in real world scenarios the code expects a port and runs a DNS lookup.

Even better, why not listen at both ipv4 and ipv6 by default?

l, err := net.Listen("tcp", ":0")
@ianlancetaylor ianlancetaylor changed the title httptest.Server uses ipv4 instead of using both Ipv4 and Ipv6 net/http/httptest: Server uses ipv4 instead of using both Ipv4 and Ipv6 Jan 8, 2025
@ianlancetaylor
Copy link
Member

CC @neild

@seankhliao
Copy link
Member

Duplicate of #56998

@seankhliao seankhliao marked this as a duplicate of #56998 Jan 8, 2025
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants