查看源码,在net/http/COOKIE.go中,可以看到
- golang1.12将COOKIE直接做了分割strings.Split(strings.TrimSpace(line), ";"),所以无论分号在什么位置都能解析出来
- 在golang1.13中 if splitIndex := strings.Index(line, ";"); splitIndex > 0 ,使用这种切割方式,如果引号位于第一个,整个获取过程便结束了,无法获得正确的COOKIE值
golang1.12
// readCOOKIEs parses all "COOKIE" values from the header h and
// returns the successfully parsed COOKIEs.
//
// if filter isn't empty, only COOKIEs of that name are returned
func readCOOKIEs(h Header, filter string) []*COOKIE {
lines, ok := h["COOKIE"]
if !ok {
return []*COOKIE{}
}
COOKIEs := []*COOKIE{}
for _, line := range lines {
parts := strings.Split(strings.TrimSpace(line), ";")
if len(parts) == 1 && parts[0] == "" {
continue
}
// Per-line attributes
for i := 0; i = 0 {
name, val = name[:j], name[j+1:]
}
if !isCOOKIENameValid(name) {
continue
}
if filter != "" && filter != name {
continue
}
val, ok := parseCOOKIEValue(val, true)
if !ok {
continue
}
COOKIEs = append(COOKIEs, &COOKIE{Name: name, Value: val})
}
}
return COOKIEs
}
golang1.13
// readCOOKIEs parses all "COOKIE" values from the header h and
// returns the successfully parsed COOKIEs.
//
// if filter isn't empty, only COOKIEs of that name are returned
func readCOOKIEs(h Header, filter string) []*COOKIE {
lines := h["COOKIE"]
if len(lines) == 0 {
return []*COOKIE{}
}
COOKIEs := make([]*COOKIE, 0, len(lines)+strings.Count(lines[0], ";"))
for _, line := range lines {
line = strings.TrimSpace(line)
var part string
for len(line) > 0 { // continue since we have rest
if splitIndex := strings.Index(line, ";"); splitIndex > 0 {
part, line = line[:splitIndex], line[splitIndex+1:]
} else {
part, line = line, ""
}
part = strings.TrimSpace(part)
if len(part) == 0 {
continue
}
name, val := part, ""
if j := strings.Index(part, "="); j >= 0 {
name, val = name[:j], name[j+1:]
}
if !isCOOKIENameValid(name) {
continue
}
if filter != "" && filter != name {
continue
}
val, ok := parseCOOKIEValue(val, true)
if !ok {
continue
}
COOKIEs = append(COOKIEs, &COOKIE{Name: name, Value: val})
}
}
return COOKIEs
}