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/httptrace: Successive HTTP requests call trace function only once when using DefaultTransport #43953

Closed
NouamaneTazi opened this issue Jan 27, 2021 · 5 comments

Comments

@NouamaneTazi
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.15.7 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Nouamane\AppData\Local\go-build
set GOENV=C:\Users\Nouamane\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\Nouamane\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Nouamane\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=D:\Projets\Hello World\Go\monitoring\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\Nouamane\AppData\Local\Temp\go-build681082894=/tmp/go-build -gno-record-gcc-switches

What did you do?

package main

import (
	"context"
	"log"
	"net/http"
	"net/http/httptrace"
	"time"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://www.google.com", nil)
	if err != nil {
		log.Fatalf("unable to create request: %v", err)
	}

	for {
		trace := &httptrace.ClientTrace{
			ConnectStart: func(_, _ string) {
				println("this should be printed infinitely but it doesn't")
			},
		}
		req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))

		client := &http.Client{
			// Transport: &http.Transport{}, // when we uncomment this line it works fine
		}
		_, err := client.Do(req)
		if err != nil {
			log.Fatalf("failed to read response: %v", err)
		}
		time.Sleep(2)
	}
}

What did you expect to see?

Infinite logs

this should be printed infinitely
this should be printed infinitely
this should be printed infinitely
this should be printed infinitely
...

What did you see instead?

I get only one line of log

this should be printed infinitely

I don't understand why the DefaultTransport behaves differently.

@toothrot toothrot changed the title Successive HTTP requests call trace function only once when using DefaultTransport x/net/http/httptrace: Successive HTTP requests call trace function only once when using DefaultTransport Jan 27, 2021
@gopherbot gopherbot added this to the Unreleased milestone Jan 27, 2021
@toothrot toothrot changed the title x/net/http/httptrace: Successive HTTP requests call trace function only once when using DefaultTransport net/http/httptrace: Successive HTTP requests call trace function only once when using DefaultTransport Jan 27, 2021
@seankhliao
Copy link
Member

from https://golang.org/pkg/net/http/httptrace/#ClientTrace , emphasis mine:

ConnectStart is called when a new connection's Dial begins.

There are other hooks for determining if a connection is resused

I believe this is working as intended

@toothrot
Copy link
Contributor

Are you certain the connection isn't being reused? See https://pkg.go.dev/net/http#DefaultTransport

@NouamaneTazi
Copy link
Author

@seankhliao It's not only ConnectStart. It was just an example. But i believe any function in ClientTrace gets only called once.

@seankhliao
Copy link
Member

seankhliao commented Jan 27, 2021

adding

			GotConn: func(gci httptrace.GotConnInfo) {
				println("resused:", gci.Reused)
			},

I get

this should be printed infinitely but it doesn't
resused: false
resused: true
resused: true
resused: true
resused: true
resused: true
resused: true
resused: true
resused: true
resused: true
resused: true

@NouamaneTazi
Copy link
Author

Thanks. I think the docs weren't clear enough for me. But I still don't see why this initialization would behave differently

client := &http.Client{
	Transport: &http.Transport{},
}

than this one:

client := &http.Client{}

Otherwise your previous comment does indeed clear my confusion.

@golang golang locked and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants