Commit 3933cb23 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

http: fix Set-Cookie date parsing

Fixes #1855

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/4527073
parent b3d3762b
...@@ -81,12 +81,17 @@ func readSetCookies(h Header) []*Cookie { ...@@ -81,12 +81,17 @@ func readSetCookies(h Header) []*Cookie {
if j := strings.Index(attr, "="); j >= 0 { if j := strings.Index(attr, "="); j >= 0 {
attr, val = attr[:j], attr[j+1:] 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 { if !success {
c.Unparsed = append(c.Unparsed, parts[i]) c.Unparsed = append(c.Unparsed, parts[i])
continue continue
} }
switch strings.ToLower(attr) { switch lowerAttr {
case "secure": case "secure":
c.Secure = true c.Secure = true
continue continue
...@@ -112,8 +117,11 @@ func readSetCookies(h Header) []*Cookie { ...@@ -112,8 +117,11 @@ func readSetCookies(h Header) []*Cookie {
c.RawExpires = val c.RawExpires = val
exptime, err := time.Parse(time.RFC1123, val) exptime, err := time.Parse(time.RFC1123, val)
if err != nil { if err != nil {
c.Expires = time.Time{} exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
break if err != nil {
c.Expires = time.Time{}
break
}
} }
c.Expires = *exptime c.Expires = *exptime
continue continue
...@@ -272,7 +280,7 @@ func unquoteCookieValue(v string) string { ...@@ -272,7 +280,7 @@ func unquoteCookieValue(v string) string {
} }
func isCookieByte(c byte) bool { func isCookieByte(c byte) bool {
switch true { switch {
case c == 0x21, 0x23 <= c && c <= 0x2b, 0x2d <= c && c <= 0x3a, case c == 0x21, 0x23 <= c && c <= 0x2b, 0x2d <= c && c <= 0x3a,
0x3c <= c && c <= 0x5b, 0x5d <= c && c <= 0x7e: 0x3c <= c && c <= 0x5b, 0x5d <= c && c <= 0x7e:
return true return true
...@@ -280,10 +288,22 @@ func isCookieByte(c byte) bool { ...@@ -280,10 +288,22 @@ func isCookieByte(c byte) bool {
return false return false
} }
func isCookieExpiresByte(c byte) (ok bool) {
return isCookieByte(c) || c == ',' || c == ' '
}
func parseCookieValue(raw string) (string, bool) { 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) raw = unquoteCookieValue(raw)
for i := 0; i < len(raw); i++ { for i := 0; i < len(raw); i++ {
if !isCookieByte(raw[i]) { if !validByte(raw[i]) {
return "", false return "", false
} }
} }
......
...@@ -11,9 +11,9 @@ import ( ...@@ -11,9 +11,9 @@ import (
"os" "os"
"reflect" "reflect"
"testing" "testing"
"time"
) )
var writeSetCookiesTests = []struct { var writeSetCookiesTests = []struct {
Cookies []*Cookie Cookies []*Cookie
Raw string Raw string
...@@ -115,6 +115,19 @@ var readSetCookiesTests = []struct { ...@@ -115,6 +115,19 @@ var readSetCookiesTests = []struct {
Header{"Set-Cookie": {"Cookie-1=v$1"}}, Header{"Set-Cookie": {"Cookie-1=v$1"}},
[]*Cookie{&Cookie{Name: "Cookie-1", Value: "v$1", Raw: "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 { func toJSON(v interface{}) string {
......
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