aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-05-24 08:31:43 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-05-24 08:31:43 -0700
commit3933cb2371d6a0ffbd5d6bb47435bde4006fb917 (patch)
treef9297d95c06d640c7ce5e0b68ab25c9462e6b589 /src/pkg/http
parentb3d3762b2ea99eab54d8c760a069b1a8d920bfb1 (diff)
downloadgo-3933cb2371d6a0ffbd5d6bb47435bde4006fb917.tar.xz
http: fix Set-Cookie date parsing
Fixes #1855 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4527073
Diffstat (limited to 'src/pkg/http')
-rw-r--r--src/pkg/http/cookie.go32
-rw-r--r--src/pkg/http/cookie_test.go15
2 files changed, 40 insertions, 7 deletions
diff --git a/src/pkg/http/cookie.go b/src/pkg/http/cookie.go
index 5add1ccc26..eb61a7001e 100644
--- a/src/pkg/http/cookie.go
+++ b/src/pkg/http/cookie.go
@@ -81,12 +81,17 @@ func readSetCookies(h Header) []*Cookie {
if j := strings.Index(attr, "="); j >= 0 {
attr, val = attr[:j], attr[j+1:]
}
- val, success = parseCookieValue(val)
+ lowerAttr := strings.ToLower(attr)
+ parseCookieValueFn := parseCookieValue
+ if lowerAttr == "expires" {
+ parseCookieValueFn = parseCookieExpiresValue
+ }
+ val, success = parseCookieValueFn(val)
if !success {
c.Unparsed = append(c.Unparsed, parts[i])
continue
}
- switch strings.ToLower(attr) {
+ switch lowerAttr {
case "secure":
c.Secure = true
continue
@@ -112,8 +117,11 @@ func readSetCookies(h Header) []*Cookie {
c.RawExpires = val
exptime, err := time.Parse(time.RFC1123, val)
if err != nil {
- c.Expires = time.Time{}
- break
+ exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
+ if err != nil {
+ c.Expires = time.Time{}
+ break
+ }
}
c.Expires = *exptime
continue
@@ -272,7 +280,7 @@ func unquoteCookieValue(v string) string {
}
func isCookieByte(c byte) bool {
- switch true {
+ switch {
case c == 0x21, 0x23 <= c && c <= 0x2b, 0x2d <= c && c <= 0x3a,
0x3c <= c && c <= 0x5b, 0x5d <= c && c <= 0x7e:
return true
@@ -280,10 +288,22 @@ func isCookieByte(c byte) bool {
return false
}
+func isCookieExpiresByte(c byte) (ok bool) {
+ return isCookieByte(c) || c == ',' || c == ' '
+}
+
func parseCookieValue(raw string) (string, bool) {
+ return parseCookieValueUsing(raw, isCookieByte)
+}
+
+func parseCookieExpiresValue(raw string) (string, bool) {
+ return parseCookieValueUsing(raw, isCookieExpiresByte)
+}
+
+func parseCookieValueUsing(raw string, validByte func(byte) bool) (string, bool) {
raw = unquoteCookieValue(raw)
for i := 0; i < len(raw); i++ {
- if !isCookieByte(raw[i]) {
+ if !validByte(raw[i]) {
return "", false
}
}
diff --git a/src/pkg/http/cookie_test.go b/src/pkg/http/cookie_test.go
index 13c9fff4ae..02e42226bd 100644
--- a/src/pkg/http/cookie_test.go
+++ b/src/pkg/http/cookie_test.go
@@ -11,9 +11,9 @@ import (
"os"
"reflect"
"testing"
+ "time"
)
-
var writeSetCookiesTests = []struct {
Cookies []*Cookie
Raw string
@@ -115,6 +115,19 @@ var readSetCookiesTests = []struct {
Header{"Set-Cookie": {"Cookie-1=v$1"}},
[]*Cookie{&Cookie{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}},
},
+ {
+ Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}},
+ []*Cookie{&Cookie{
+ Name: "NID",
+ Value: "99=YsDT5i3E-CXax-",
+ Path: "/",
+ Domain: ".google.ch",
+ HttpOnly: true,
+ Expires: time.Time{Year: 2011, Month: 11, Day: 23, Hour: 1, Minute: 5, Second: 3, Weekday: 3, ZoneOffset: 0, Zone: "GMT"},
+ RawExpires: "Wed, 23-Nov-2011 01:05:03 GMT",
+ Raw: "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly",
+ }},
+ },
}
func toJSON(v interface{}) string {