Understanding net/http.Client Redirect Behavior and Cookie Handling in Go
This article explains why a Go http.Client does not automatically carry cookies during redirects, how the default redirect logic works for different HTTP methods, and how to enable cookie storage with CookieJar or disable redirects using CheckRedirect.
The author, a Go developer at Qunar, wrote an HTTP client to simulate a website login that validates credentials, issues a token via cookie, and redirects to the homepage, but the default http.DefaultClient.Do(request) did not produce the expected response.
By examining the net/http library, we see that automatic redirects are performed for GET, HEAD, POST, and PUT requests, with specific status codes (301, 302, 303, 307 for GET/HEAD; 302, 303 for POST/PUT) determined by the shouldRedirectGet and shouldRedirectPost functions.
The failure occurs because, during a redirect, the client does not retain cookies from the previous response unless a CookieJar is provided; consequently, the subsequent request lacks the required cookie.
The CookieJar field in http.Client stores cookies in memory. It implements the SetCookies and Cookies methods, and its concrete implementation resides in net/http/cookiejar . Internally, cookies are kept in a double‑map structure where the first key is the domain suffix (based on a PublicSuffixList) and the second key combines cookie name, domain, and path.
To make redirects carry cookies, simply assign a jar to the client, e.g., client.Jar = cookiejar.New(nil) . This enables the client to save cookies from the initial response and include them in the redirected request.
The matching rules for cookies depend on the PublicSuffixList . When Jar.pList is nil, a default rule extracts the effective top‑level domain (e.g., http://b.com from http://a.b.com ). If a custom list is provided, its implementation determines the key.
If you wish to prevent the client from following redirects, set the CheckRedirect field to a function that returns http.ErrUseLastResponse , for example:
client.CheckRedirect = func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }
This stops the internal redirect loop after the first response, allowing you to handle redirects manually.
In summary, the issue is resolved by configuring a CookieJar for cookie persistence or by customizing CheckRedirect to disable automatic redirects.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.