1 Star 1 Fork 0

沙滩星空/miniutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
cookie.go 4.04 KB
一键复制 编辑 原始数据 按行查看 历史
沙滩星空 提交于 2023-02-07 14:34 +08:00 . Compatible gov1.18 and ADD cookie
package miniutils
import (
"net/http"
"net/textproto"
"strconv"
"strings"
"time"
"golang.org/x/net/http/httpguts"
)
// Copy "from net/http",cookie.go
// readSetCookies parses all "Set-Cookie" values from
// the header h and returns the successfully parsed Cookies.
func ReadSetCookies(h http.Header) []*http.Cookie {
cookieCount := len(h["Set-Cookie"])
if cookieCount == 0 {
return []*http.Cookie{}
}
cookies := make([]*http.Cookie, 0, cookieCount)
for _, line := range h["Set-Cookie"] {
parts := strings.Split(textproto.TrimString(line), ";")
if len(parts) == 1 && parts[0] == "" {
continue
}
parts[0] = textproto.TrimString(parts[0])
name, value, ok := strings.Cut(parts[0], "=")
if !ok {
continue
}
if !isCookieNameValid(name) {
continue
}
value, ok = parseCookieValue(value, true)
if !ok {
continue
}
c := &http.Cookie{
Name: name,
Value: value,
Raw: line,
}
for i := 1; i < len(parts); i++ {
parts[i] = textproto.TrimString(parts[i])
if len(parts[i]) == 0 {
continue
}
attr, val, _ := strings.Cut(parts[i], "=")
lowerAttr, isASCII := asciiToLower(attr)
if !isASCII {
continue
}
val, ok = parseCookieValue(val, false)
if !ok {
c.Unparsed = append(c.Unparsed, parts[i])
continue
}
switch lowerAttr {
case "samesite":
lowerVal, ascii := asciiToLower(val)
if !ascii {
c.SameSite = http.SameSiteDefaultMode
continue
}
switch lowerVal {
case "lax":
c.SameSite = http.SameSiteLaxMode
case "strict":
c.SameSite = http.SameSiteStrictMode
case "none":
c.SameSite = http.SameSiteNoneMode
default:
c.SameSite = http.SameSiteDefaultMode
}
continue
case "secure":
c.Secure = true
continue
case "httponly":
c.HttpOnly = true
continue
case "domain":
c.Domain = val
continue
case "max-age":
secs, err := strconv.Atoi(val)
if err != nil || secs != 0 && val[0] == '0' {
break
}
if secs <= 0 {
secs = -1
}
c.MaxAge = secs
continue
case "expires":
c.RawExpires = 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 {
c.Expires = time.Time{}
break
}
}
c.Expires = exptime.UTC()
continue
case "path":
c.Path = val
continue
}
c.Unparsed = append(c.Unparsed, parts[i])
}
cookies = append(cookies, c)
}
return cookies
}
// 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 http.Header, filter string) []*http.Cookie {
lines := h["Cookie"]
if len(lines) == 0 {
return []*http.Cookie{}
}
cookies := make([]*http.Cookie, 0, len(lines)+strings.Count(lines[0], ";"))
for _, line := range lines {
line = textproto.TrimString(line)
var part string
for len(line) > 0 { // continue since we have rest
part, line, _ = strings.Cut(line, ";")
part = textproto.TrimString(part)
if part == "" {
continue
}
name, val, _ := strings.Cut(part, "=")
if !isCookieNameValid(name) {
continue
}
if filter != "" && filter != name {
continue
}
val, ok := parseCookieValue(val, true)
if !ok {
continue
}
cookies = append(cookies, &http.Cookie{Name: name, Value: val})
}
}
return cookies
}
func validCookieValueByte(b byte) bool {
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
}
func parseCookieValue(raw string, allowDoubleQuote bool) (string, bool) {
// Strip the quotes, if present.
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
for i := 0; i < len(raw); i++ {
if !validCookieValueByte(raw[i]) {
return "", false
}
}
return raw, true
}
func isCookieNameValid(raw string) bool {
if raw == "" {
return false
}
return strings.IndexFunc(raw, isNotToken) < 0
}
func isNotToken(r rune) bool {
return !httpguts.IsTokenRune(r)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/catmes/miniutils.git
git@gitee.com:catmes/miniutils.git
catmes
miniutils
miniutils
main

搜索帮助