Commit dd694fb1 authored by Volker Dobler's avatar Volker Dobler Committed by Russ Cox

net/http: Added interface for a cookie jar.

Types implementing CookieJar may be used in a Client
to persist cookies.

R=bradfitz, rsc
CC=golang-dev
https://golang.org/cl/5399043
parent a3008e23
...@@ -12,6 +12,7 @@ GOFILES=\ ...@@ -12,6 +12,7 @@ GOFILES=\
filetransport.go\ filetransport.go\
fs.go\ fs.go\
header.go\ header.go\
jar.go\
lex.go\ lex.go\
request.go\ request.go\
response.go\ response.go\
......
...@@ -38,6 +38,11 @@ type Client struct { ...@@ -38,6 +38,11 @@ type Client struct {
// If CheckRedirect is nil, the Client uses its default policy, // If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests. // which is to stop after 10 consecutive requests.
CheckRedirect func(req *Request, via []*Request) error CheckRedirect func(req *Request, via []*Request) error
// Jar specifies the cookie jar.
// If Jar is nil, cookies are not sent in requests and ignored
// in responses.
Jar CookieJar
} }
// DefaultClient is the default Client and is used by Get, Head, and Post. // DefaultClient is the default Client and is used by Get, Head, and Post.
...@@ -180,6 +185,11 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) { ...@@ -180,6 +185,11 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
return nil, errors.New("http: nil Request.URL") return nil, errors.New("http: nil Request.URL")
} }
jar := c.Jar
if jar == nil {
jar = blackHoleJar{}
}
req := ireq req := ireq
urlStr := "" // next relative or absolute URL to fetch (after first request) urlStr := "" // next relative or absolute URL to fetch (after first request)
for redirect := 0; ; redirect++ { for redirect := 0; ; redirect++ {
...@@ -203,12 +213,19 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) { ...@@ -203,12 +213,19 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
break break
} }
} }
for _, cookie := range jar.Cookies(req.URL) {
req.AddCookie(cookie)
}
} }
urlStr = req.URL.String() urlStr = req.URL.String()
if r, err = send(req, c.Transport); err != nil { if r, err = send(req, c.Transport); err != nil {
break break
} }
if c := r.Cookies(); len(c) > 0 {
jar.SetCookies(req.URL, c)
}
if shouldRedirect(r.StatusCode) { if shouldRedirect(r.StatusCode) {
r.Body.Close() r.Body.Close()
if urlStr = r.Header.Get("Location"); urlStr == "" { if urlStr = r.Header.Get("Location"); urlStr == "" {
......
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http
import (
"net/url"
)
// A CookieJar manages storage and use of cookies in HTTP requests.
//
// Implementations of CookieJar must be safe for concurrent use by multiple
// goroutines.
type CookieJar interface {
// SetCookies handles the receipt of the cookies in a reply for the
// given URL. It may or may not choose to save the cookies, depending
// on the jar's policy and implementation.
SetCookies(u *url.URL, cookies []*Cookie)
// Cookies returns the cookies to send in a request for the given URL.
// It is up to the implementation to honor the standard cookie use
// restrictions such as in RFC 6265.
Cookies(u *url.URL) []*Cookie
}
type blackHoleJar struct{}
func (blackHoleJar) SetCookies(u *url.URL, cookies []*Cookie) {}
func (blackHoleJar) Cookies(u *url.URL) []*Cookie { return nil }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment