mirror of
https://github.com/golang/go
synced 2024-11-25 07:17:56 -07:00
http: add http.SetCookie(ResponseWriter, *Cookie)
R=golang-dev, gary.burd, rsc CC=golang-dev https://golang.org/cl/4526062
This commit is contained in:
parent
83fd82b349
commit
9ea0bd3986
@ -130,6 +130,37 @@ func readSetCookies(h Header) []*Cookie {
|
|||||||
return cookies
|
return cookies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
|
||||||
|
func SetCookie(w ResponseWriter, cookie *Cookie) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
writeSetCookieToBuffer(&b, cookie)
|
||||||
|
w.Header().Add("Set-Cookie", b.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeSetCookieToBuffer(buf *bytes.Buffer, c *Cookie) {
|
||||||
|
fmt.Fprintf(buf, "%s=%s", sanitizeName(c.Name), sanitizeValue(c.Value))
|
||||||
|
if len(c.Path) > 0 {
|
||||||
|
fmt.Fprintf(buf, "; Path=%s", sanitizeValue(c.Path))
|
||||||
|
}
|
||||||
|
if len(c.Domain) > 0 {
|
||||||
|
fmt.Fprintf(buf, "; Domain=%s", sanitizeValue(c.Domain))
|
||||||
|
}
|
||||||
|
if len(c.Expires.Zone) > 0 {
|
||||||
|
fmt.Fprintf(buf, "; Expires=%s", c.Expires.Format(time.RFC1123))
|
||||||
|
}
|
||||||
|
if c.MaxAge > 0 {
|
||||||
|
fmt.Fprintf(buf, "; Max-Age=%d", c.MaxAge)
|
||||||
|
} else if c.MaxAge < 0 {
|
||||||
|
fmt.Fprintf(buf, "; Max-Age=0")
|
||||||
|
}
|
||||||
|
if c.HttpOnly {
|
||||||
|
fmt.Fprintf(buf, "; HttpOnly")
|
||||||
|
}
|
||||||
|
if c.Secure {
|
||||||
|
fmt.Fprintf(buf, "; Secure")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// writeSetCookies writes the wire representation of the set-cookies
|
// writeSetCookies writes the wire representation of the set-cookies
|
||||||
// to w. Each cookie is written on a separate "Set-Cookie: " line.
|
// to w. Each cookie is written on a separate "Set-Cookie: " line.
|
||||||
// This choice is made because HTTP parsers tend to have a limit on
|
// This choice is made because HTTP parsers tend to have a limit on
|
||||||
@ -142,27 +173,7 @@ func writeSetCookies(w io.Writer, kk []*Cookie) os.Error {
|
|||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
for _, c := range kk {
|
for _, c := range kk {
|
||||||
b.Reset()
|
b.Reset()
|
||||||
fmt.Fprintf(&b, "%s=%s", sanitizeName(c.Name), sanitizeValue(c.Value))
|
writeSetCookieToBuffer(&b, c)
|
||||||
if len(c.Path) > 0 {
|
|
||||||
fmt.Fprintf(&b, "; Path=%s", sanitizeValue(c.Path))
|
|
||||||
}
|
|
||||||
if len(c.Domain) > 0 {
|
|
||||||
fmt.Fprintf(&b, "; Domain=%s", sanitizeValue(c.Domain))
|
|
||||||
}
|
|
||||||
if len(c.Expires.Zone) > 0 {
|
|
||||||
fmt.Fprintf(&b, "; Expires=%s", c.Expires.Format(time.RFC1123))
|
|
||||||
}
|
|
||||||
if c.MaxAge > 0 {
|
|
||||||
fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
|
|
||||||
} else if c.MaxAge < 0 {
|
|
||||||
fmt.Fprintf(&b, "; Max-Age=0")
|
|
||||||
}
|
|
||||||
if c.HttpOnly {
|
|
||||||
fmt.Fprintf(&b, "; HttpOnly")
|
|
||||||
}
|
|
||||||
if c.Secure {
|
|
||||||
fmt.Fprintf(&b, "; Secure")
|
|
||||||
}
|
|
||||||
lines = append(lines, "Set-Cookie: "+b.String()+"\r\n")
|
lines = append(lines, "Set-Cookie: "+b.String()+"\r\n")
|
||||||
}
|
}
|
||||||
sort.SortStrings(lines)
|
sort.SortStrings(lines)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"json"
|
"json"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -43,6 +44,35 @@ func TestWriteSetCookies(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type headerOnlyResponseWriter Header
|
||||||
|
|
||||||
|
func (ho headerOnlyResponseWriter) Header() Header {
|
||||||
|
return Header(ho)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ho headerOnlyResponseWriter) Write([]byte) (int, os.Error) {
|
||||||
|
panic("NOIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ho headerOnlyResponseWriter) WriteHeader(int) {
|
||||||
|
panic("NOIMPL")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetCookie(t *testing.T) {
|
||||||
|
m := make(Header)
|
||||||
|
SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-1", Value: "one", Path: "/restricted/"})
|
||||||
|
SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600})
|
||||||
|
if l := len(m["Set-Cookie"]); l != 2 {
|
||||||
|
t.Fatalf("expected %d cookies, got %d", 2, l)
|
||||||
|
}
|
||||||
|
if g, e := m["Set-Cookie"][0], "cookie-1=one; Path=/restricted/"; g != e {
|
||||||
|
t.Errorf("cookie #1: want %q, got %q", e, g)
|
||||||
|
}
|
||||||
|
if g, e := m["Set-Cookie"][1], "cookie-2=two; Max-Age=3600"; g != e {
|
||||||
|
t.Errorf("cookie #2: want %q, got %q", e, g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var writeCookiesTests = []struct {
|
var writeCookiesTests = []struct {
|
||||||
Cookies []*Cookie
|
Cookies []*Cookie
|
||||||
Raw string
|
Raw string
|
||||||
|
Loading…
Reference in New Issue
Block a user