🐛 尝试解决cookie jar的问题
This commit is contained in:
@@ -67,7 +67,23 @@ func (a *AllSavePersistCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie)
|
|||||||
if a.domainMap[mainDomain] == nil {
|
if a.domainMap[mainDomain] == nil {
|
||||||
a.domainMap[mainDomain] = make(cookieMap)
|
a.domainMap[mainDomain] = make(cookieMap)
|
||||||
}
|
}
|
||||||
a.domainMap[mainDomain][cookie.Name] = cookie
|
|
||||||
|
// 查找是否存在相同 name, path 和 domain 的 cookie
|
||||||
|
existingCookies := a.domainMap[mainDomain][cookie.Name]
|
||||||
|
found := false
|
||||||
|
for i, existing := range existingCookies {
|
||||||
|
if existing.Path == cookie.Path && existing.Domain == cookie.Domain {
|
||||||
|
// 找到完全匹配的 cookie,替换它
|
||||||
|
existingCookies[i] = cookie
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
// 没有找到匹配的,添加新的 cookie
|
||||||
|
a.domainMap[mainDomain][cookie.Name] = append(a.domainMap[mainDomain][cookie.Name], cookie)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +94,43 @@ func (a *AllSavePersistCookieJar) Cookies(u *url.URL) []*http.Cookie {
|
|||||||
// 提取主域名
|
// 提取主域名
|
||||||
mainDomain := extractMainDomain(u.Host)
|
mainDomain := extractMainDomain(u.Host)
|
||||||
|
|
||||||
if cookies, exists := a.domainMap[mainDomain]; exists {
|
if cookiesList, exists := a.domainMap[mainDomain]; exists {
|
||||||
result := make([]*http.Cookie, 0, len(cookies))
|
result := make([]*http.Cookie, 0, len(cookiesList))
|
||||||
for _, cookie := range cookies {
|
requestPath := u.Path
|
||||||
result = append(result, cookie)
|
if requestPath == "" {
|
||||||
|
requestPath = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cookies := range cookiesList {
|
||||||
|
// 如果只有一个 cookie,直接返回
|
||||||
|
if len(cookies) == 1 {
|
||||||
|
result = append(result, cookies[0])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 有多个同名 cookie,选择最匹配的(path 最长且匹配请求路径的)
|
||||||
|
var bestMatch *http.Cookie
|
||||||
|
bestMatchLen := -1
|
||||||
|
|
||||||
|
for _, cookie := range cookies {
|
||||||
|
cookiePath := cookie.Path
|
||||||
|
if cookiePath == "" {
|
||||||
|
cookiePath = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 path 是否匹配
|
||||||
|
if pathMatch(requestPath, cookiePath) {
|
||||||
|
if len(cookiePath) > bestMatchLen {
|
||||||
|
bestMatch = cookie
|
||||||
|
bestMatchLen = len(cookiePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果找到匹配的,添加到结果中
|
||||||
|
if bestMatch != nil {
|
||||||
|
result = append(result, bestMatch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,47 +3,19 @@ package cookiejar
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
|
||||||
"github.com/bytedance/sonic"
|
|
||||||
"io"
|
"io"
|
||||||
"likedream-goframe/internal/utils"
|
"likedream-goframe/internal/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/bytedance/sonic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hostMap map[string]cookieMap
|
type hostMap map[string]cookieMap
|
||||||
|
|
||||||
type cookieMap map[string]*http.Cookie
|
type cookieMap map[string][]*http.Cookie
|
||||||
|
|
||||||
// cookieKey 生成 cookie 的唯一标识 key,使用 name 和 path 的组合
|
|
||||||
func cookieKey(name, path string) string {
|
|
||||||
return fmt.Sprintf("%s|%s", name, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pathMatch 检查请求路径是否匹配 cookie 的 path
|
|
||||||
// 根据 RFC 6265 Section 5.1.4
|
|
||||||
func pathMatch(requestPath, cookiePath string) bool {
|
|
||||||
// 如果路径完全相同
|
|
||||||
if requestPath == cookiePath {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果 cookie path 是请求 path 的前缀
|
|
||||||
if strings.HasPrefix(requestPath, cookiePath) {
|
|
||||||
// cookie path 以 / 结尾,或者请求 path 在 cookie path 后紧跟 /
|
|
||||||
if strings.HasSuffix(cookiePath, "/") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if len(requestPath) > len(cookiePath) && requestPath[len(cookiePath)] == '/' {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type PersistCookieJar struct {
|
type PersistCookieJar struct {
|
||||||
hostMap hostMap
|
hostMap hostMap
|
||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
@@ -63,7 +35,7 @@ func (p *PersistCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
|
|||||||
host := u.Host
|
host := u.Host
|
||||||
|
|
||||||
if _, exists := p.hostMap[host]; !exists {
|
if _, exists := p.hostMap[host]; !exists {
|
||||||
p.hostMap = make(hostMap)
|
p.hostMap[host] = make(cookieMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cookie := range cookies {
|
for _, cookie := range cookies {
|
||||||
@@ -71,21 +43,21 @@ func (p *PersistCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
|
|||||||
p.hostMap[host] = make(cookieMap)
|
p.hostMap[host] = make(cookieMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果 cookie 没有设置 Path,使用默认值 "/"
|
// 查找是否存在相同 name, path 和 domain 的 cookie
|
||||||
cookiePath := cookie.Path
|
existingCookies := p.hostMap[host][cookie.Name]
|
||||||
if cookiePath == "" {
|
found := false
|
||||||
cookiePath = "/"
|
for i, existing := range existingCookies {
|
||||||
|
if existing.Path == cookie.Path && existing.Domain == cookie.Domain {
|
||||||
|
// 找到完全匹配的 cookie,替换它
|
||||||
|
existingCookies[i] = cookie
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 name 和 path 的组合作为 key
|
if !found {
|
||||||
key := cookieKey(cookie.Name, cookiePath)
|
// 没有找到匹配的,添加新的 cookie
|
||||||
|
p.hostMap[host][cookie.Name] = append(p.hostMap[host][cookie.Name], cookie)
|
||||||
// 如果 MaxAge=0 或 MaxAge<0,表示删除 cookie
|
|
||||||
// 只删除完全匹配的 cookie(name 和 path 都相同)
|
|
||||||
if cookie.MaxAge < 0 || (cookie.MaxAge == 0 && cookie.Value == "") {
|
|
||||||
delete(p.hostMap[host], key)
|
|
||||||
} else {
|
|
||||||
p.hostMap[host][key] = cookie
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,22 +68,42 @@ func (p *PersistCookieJar) Cookies(u *url.URL) []*http.Cookie {
|
|||||||
defer p.RUnlock()
|
defer p.RUnlock()
|
||||||
|
|
||||||
host := u.Host
|
host := u.Host
|
||||||
requestPath := u.Path
|
if cookiesList, exists := p.hostMap[host]; exists {
|
||||||
if requestPath == "" {
|
result := make([]*http.Cookie, 0, len(cookiesList))
|
||||||
requestPath = "/"
|
requestPath := u.Path
|
||||||
}
|
if requestPath == "" {
|
||||||
|
requestPath = "/"
|
||||||
|
}
|
||||||
|
|
||||||
if cookies, exists := p.hostMap[host]; exists {
|
for _, cookies := range cookiesList {
|
||||||
result := make([]*http.Cookie, 0, len(cookies))
|
// 如果只有一个 cookie,直接返回
|
||||||
for _, cookie := range cookies {
|
if len(cookies) == 1 {
|
||||||
// 检查 cookie 的 path 是否匹配请求的 path
|
result = append(result, cookies[0])
|
||||||
cookiePath := cookie.Path
|
continue
|
||||||
if cookiePath == "" {
|
|
||||||
cookiePath = "/"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if pathMatch(requestPath, cookiePath) {
|
// 有多个同名 cookie,选择最匹配的(path 最长且匹配请求路径的)
|
||||||
result = append(result, cookie)
|
var bestMatch *http.Cookie
|
||||||
|
bestMatchLen := -1
|
||||||
|
|
||||||
|
for _, cookie := range cookies {
|
||||||
|
cookiePath := cookie.Path
|
||||||
|
if cookiePath == "" {
|
||||||
|
cookiePath = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 path 是否匹配
|
||||||
|
if pathMatch(requestPath, cookiePath) {
|
||||||
|
if len(cookiePath) > bestMatchLen {
|
||||||
|
bestMatch = cookie
|
||||||
|
bestMatchLen = len(cookiePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果找到匹配的,添加到结果中
|
||||||
|
if bestMatch != nil {
|
||||||
|
result = append(result, bestMatch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@@ -119,6 +111,26 @@ func (p *PersistCookieJar) Cookies(u *url.URL) []*http.Cookie {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pathMatch 检查请求路径是否匹配 cookie 的 path
|
||||||
|
// 根据 RFC 6265 的规则
|
||||||
|
func pathMatch(requestPath, cookiePath string) bool {
|
||||||
|
if requestPath == cookiePath {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(requestPath, cookiePath) {
|
||||||
|
// cookiePath 以 / 结尾,或者 requestPath 的下一个字符是 /
|
||||||
|
if strings.HasSuffix(cookiePath, "/") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if len(requestPath) > len(cookiePath) && requestPath[len(cookiePath)] == '/' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PersistCookieJar) Serialize() string {
|
func (p *PersistCookieJar) Serialize() string {
|
||||||
p.RLock()
|
p.RLock()
|
||||||
defer p.RUnlock()
|
defer p.RUnlock()
|
||||||
|
|||||||
@@ -450,11 +450,11 @@ func submitCasKickOut(ctx context.Context, requestUrl string, doc *goquery.Docum
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCasValidLoginUrl(info *school.SchoolDetailInfo) string {
|
func getCasValidLoginUrl(info *school.SchoolDetailInfo) string {
|
||||||
if strings.Contains(info.AmpUrl, "campusphere") {
|
if strings.Contains(info.AmpUrl, "campusphere") || strings.Contains(info.AmpUrl, "wec-portal-mobile") {
|
||||||
return info.AmpUrl
|
return info.AmpUrl
|
||||||
} else if strings.Contains(info.AmpUrl2, "campusphere") {
|
} else if strings.Contains(info.AmpUrl2, "campusphere") || strings.Contains(info.AmpUrl2, "wec-portal-mobile") {
|
||||||
return info.AmpUrl2
|
return info.AmpUrl2
|
||||||
} else if strings.Contains(info.AmpUrl3, "campusphere") {
|
} else if strings.Contains(info.AmpUrl3, "campusphere") || strings.Contains(info.AmpUrl3, "wec-portal-mobile") {
|
||||||
return info.AmpUrl3
|
return info.AmpUrl3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user