]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: Added interface for a cookie jar.
authorVolker Dobler <dr.volker.dobler@gmail.com>
Fri, 16 Dec 2011 15:48:41 +0000 (10:48 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 16 Dec 2011 15:48:41 +0000 (10:48 -0500)
Types implementing CookieJar may be used in a Client
to persist cookies.

R=bradfitz, rsc
CC=golang-dev
https://golang.org/cl/5399043

src/pkg/net/http/Makefile
src/pkg/net/http/client.go
src/pkg/net/http/jar.go [new file with mode: 0644]

index 807bc32447c74705d000686b2084cc247dc1da40..5c351b0c403eeeda1df62ec7695ac8241fb20cfc 100644 (file)
@@ -12,6 +12,7 @@ GOFILES=\
        filetransport.go\
        fs.go\
        header.go\
+       jar.go\
        lex.go\
        request.go\
        response.go\
index 211ac44c58a9d92f5c4672d91d1029938acd7274..a4f8f19aac84d4662d083616d3c4c89379f34791 100644 (file)
@@ -38,6 +38,11 @@ type Client struct {
        // If CheckRedirect is nil, the Client uses its default policy,
        // which is to stop after 10 consecutive requests.
        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.
@@ -180,6 +185,11 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
                return nil, errors.New("http: nil Request.URL")
        }
 
+       jar := c.Jar
+       if jar == nil {
+               jar = blackHoleJar{}
+       }
+
        req := ireq
        urlStr := "" // next relative or absolute URL to fetch (after first request)
        for redirect := 0; ; redirect++ {
@@ -203,12 +213,19 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
                                        break
                                }
                        }
+                       for _, cookie := range jar.Cookies(req.URL) {
+                               req.AddCookie(cookie)
+                       }
                }
 
                urlStr = req.URL.String()
                if r, err = send(req, c.Transport); err != nil {
                        break
                }
+               if c := r.Cookies(); len(c) > 0 {
+                       jar.SetCookies(req.URL, c)
+               }
+
                if shouldRedirect(r.StatusCode) {
                        r.Body.Close()
                        if urlStr = r.Header.Get("Location"); urlStr == "" {
diff --git a/src/pkg/net/http/jar.go b/src/pkg/net/http/jar.go
new file mode 100644 (file)
index 0000000..2c2caa2
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 }