Skip to content

net/http: Request.Clone does not clone path values #64911

Closed
@nussjustin

Description

@nussjustin

Go version

go version go1.22rc1 linux/amd64

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

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/justinn/.cache/go-build'
GOENV='/home/justinn/.config/go/env'
GOEXE=''
GOEXPERIMENT='loopvar'
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/justinn/.gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/justinn/.gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/justinn/sdk/go1.22rc1'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/justinn/sdk/go1.22rc1/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22rc1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/justinn/Downloads/t/go.mod'
GOWORK=''
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-build1649121262=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I tried using the new Request.PathValue and Request.SetPathValue methods introduced in #61410 together with Request.Clone.

Code:

	orig, err := http.NewRequest("GET", "https://example.com/", nil)
	if err != nil {
		panic(err)
	}
	orig.SetPathValue("orig", "orig")

	copy := orig.Clone(context.Background())
	copy.SetPathValue("copy", "copy")

	fmt.Println(orig.PathValue("orig") == "orig") // true
	fmt.Println(orig.PathValue("copy") == "")     // false, should be true

	fmt.Println(copy.PathValue("orig") == "orig") // true
	fmt.Println(copy.PathValue("copy") == "copy") // true

Playground Link: https://go.dev/play/p/gz8wPsLmz6u?v=gotip

What did you expect to see?

Request.Clones documentation states

// Clone returns a deep copy of r with its context changed to ctx.

Thus I expect calls to SetPathValue on one request object to not affect the values returned by PathValue on the other request object.

What did you see instead?

Changes to the path values of one request also affect the other. See the example code and the playground example.

The reason for this is that Clone does not create copies of r.matches and r.otherValues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions