mirror of
https://github.com/golang/go
synced 2024-11-22 06:34:40 -07:00
http: fix Set-Cookie date parsing
Fixes #1855 R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4527073
This commit is contained in:
parent
b3d3762b2e
commit
3933cb2371
@ -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
|
||||||
@ -111,10 +116,13 @@ func readSetCookies(h Header) []*Cookie {
|
|||||||
case "expires":
|
case "expires":
|
||||||
c.RawExpires = val
|
c.RawExpires = val
|
||||||
exptime, err := time.Parse(time.RFC1123, val)
|
exptime, err := time.Parse(time.RFC1123, val)
|
||||||
|
if err != nil {
|
||||||
|
exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Expires = time.Time{}
|
c.Expires = time.Time{}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c.Expires = *exptime
|
c.Expires = *exptime
|
||||||
continue
|
continue
|
||||||
case "path":
|
case "path":
|
||||||
@ -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 {
|
|||||||
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 (
|
|||||||
"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 {
|
|||||||
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user