aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean Liao <sean@liao.dev>2025-10-08 22:33:24 +0100
committerGopher Robot <gobot@golang.org>2025-10-10 14:38:20 -0700
commit69e82796322bbff60b522534a8a6eacb2bf1ebba (patch)
tree57dee1f0f5ad55930b88371a580e0952175d7c9d /src
parent6f4c63ba63fdec6e4a42e2e19ac71937973dedef (diff)
downloadgo-69e82796322bbff60b522534a8a6eacb2bf1ebba.tar.xz
net/http: set cookie host to Request.Host when available
When both Request.URL and Request.Host are set, the host in URL is used for connecting at the transport level, while Host is used for the request host line. Cookies should be set for the request, not the underlying connection destination. Fixes #38988 Change-Id: I09053b87ccac67081f6038d205837d9763701526 Reviewed-on: https://go-review.googlesource.com/c/go/+/710335 Reviewed-by: Damien Neil <dneil@google.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/net/http/client.go9
-rw-r--r--src/net/http/client_test.go30
2 files changed, 37 insertions, 2 deletions
diff --git a/src/net/http/client.go b/src/net/http/client.go
index ba095ea1e3..8faab2b17a 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -172,8 +172,13 @@ func refererForURL(lastReq, newReq *url.URL, explicitRef string) string {
// didTimeout is non-nil only if err != nil.
func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
+ cookieURL := req.URL
+ if req.Host != "" {
+ cookieURL = cloneURL(cookieURL)
+ cookieURL.Host = req.Host
+ }
if c.Jar != nil {
- for _, cookie := range c.Jar.Cookies(req.URL) {
+ for _, cookie := range c.Jar.Cookies(cookieURL) {
req.AddCookie(cookie)
}
}
@@ -183,7 +188,7 @@ func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTime
}
if c.Jar != nil {
if rc := resp.Cookies(); len(rc) > 0 {
- c.Jar.SetCookies(req.URL, rc)
+ c.Jar.SetCookies(cookieURL, rc)
}
}
return resp, nil, nil
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index 94fddb508e..2a3ee385f3 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -585,6 +585,36 @@ var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request)
}
})
+func TestHostMismatchCookies(t *testing.T) { run(t, testHostMismatchCookies) }
+func testHostMismatchCookies(t *testing.T, mode testMode) {
+ ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+ for _, c := range r.Cookies() {
+ c.Value = "SetOnServer"
+ SetCookie(w, c)
+ }
+ })).ts
+
+ reqURL, _ := url.Parse(ts.URL)
+ hostURL := *reqURL
+ hostURL.Host = "cookies.example.com"
+
+ c := ts.Client()
+ c.Jar = new(TestJar)
+ c.Jar.SetCookies(reqURL, []*Cookie{{Name: "First", Value: "SetOnClient"}})
+ c.Jar.SetCookies(&hostURL, []*Cookie{{Name: "Second", Value: "SetOnClient"}})
+
+ req, _ := NewRequest("GET", ts.URL, NoBody)
+ req.Host = hostURL.Host
+ resp, err := c.Do(req)
+ if err != nil {
+ t.Fatalf("Get: %v", err)
+ }
+ resp.Body.Close()
+
+ matchReturnedCookies(t, []*Cookie{{Name: "First", Value: "SetOnClient"}}, c.Jar.Cookies(reqURL))
+ matchReturnedCookies(t, []*Cookie{{Name: "Second", Value: "SetOnServer"}}, c.Jar.Cookies(&hostURL))
+}
+
func TestClientSendsCookieFromJar(t *testing.T) {
defer afterTest(t)
tr := &recordingTransport{}