mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-09-10 04:19:48 +00:00
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/store"
|
|
)
|
|
|
|
type browserCookieSyncRequest struct {
|
|
AgentID string `json:"agent_id"`
|
|
Agent string `json:"agent,omitempty"`
|
|
Source string `json:"source,omitempty"`
|
|
Cookies []browserCookieSyncPayload `json:"cookies"`
|
|
}
|
|
|
|
type browserCookieSyncPayload struct {
|
|
Domain string `json:"domain"`
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
Value string `json:"value"`
|
|
URL string `json:"url,omitempty"`
|
|
Secure bool `json:"secure"`
|
|
HTTPOnly bool `json:"httpOnly"`
|
|
HTTPOnlySnake bool `json:"http_only"`
|
|
SameSite string `json:"sameSite"`
|
|
SameSiteSnake string `json:"same_site"`
|
|
ExpiresAt *time.Time `json:"expiresAt"`
|
|
ExpiresAtSnake *time.Time `json:"expires_at"`
|
|
ExpirationDate *float64 `json:"expirationDate"`
|
|
ExpirationDateSnake *float64 `json:"expiration_date"`
|
|
}
|
|
|
|
type browserCookieMetadata struct {
|
|
Domain string `json:"domain"`
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
Secure bool `json:"secure"`
|
|
HTTPOnly bool `json:"httpOnly"`
|
|
SameSite string `json:"sameSite,omitempty"`
|
|
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
|
|
Source string `json:"source,omitempty"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
}
|
|
|
|
func (p browserCookieSyncPayload) toStoreCookie(source string) (store.BrowserCookie, error) {
|
|
domain := strings.TrimSpace(p.Domain)
|
|
if domain == "" && p.URL != "" {
|
|
u, err := url.Parse(p.URL)
|
|
if err != nil {
|
|
return store.BrowserCookie{}, errBrowserCookieInvalidURL
|
|
}
|
|
domain = u.Hostname()
|
|
}
|
|
if len(p.Value) > maxBrowserCookieValueBytes {
|
|
return store.BrowserCookie{}, errBrowserCookieValueTooLarge
|
|
}
|
|
c := store.NormalizeBrowserCookie(store.BrowserCookie{
|
|
Domain: domain,
|
|
Name: p.Name,
|
|
Path: p.Path,
|
|
Value: p.Value,
|
|
Secure: p.Secure,
|
|
HTTPOnly: p.HTTPOnly || p.HTTPOnlySnake,
|
|
SameSite: firstBrowserCookieNonEmpty(p.SameSite, p.SameSiteSnake),
|
|
ExpiresAt: firstTime(p.ExpiresAt, p.ExpiresAtSnake, timeFromUnixSeconds(p.ExpirationDate), timeFromUnixSeconds(p.ExpirationDateSnake)),
|
|
Source: source,
|
|
})
|
|
if err := store.ValidateBrowserCookie(c); err != nil {
|
|
return store.BrowserCookie{}, err
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
func browserCookieFilterFromQuery(r *http.Request) store.BrowserCookieFilter {
|
|
q := r.URL.Query()
|
|
return store.BrowserCookieFilter{
|
|
Domain: q.Get("domain"),
|
|
Name: q.Get("name"),
|
|
Path: q.Get("path"),
|
|
}
|
|
}
|
|
|
|
func firstBrowserCookieNonEmpty(values ...string) string {
|
|
for _, v := range values {
|
|
if strings.TrimSpace(v) != "" {
|
|
return strings.TrimSpace(v)
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func firstTime(values ...*time.Time) *time.Time {
|
|
for _, v := range values {
|
|
if v != nil {
|
|
t := v.UTC()
|
|
return &t
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func timeFromUnixSeconds(v *float64) *time.Time {
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
sec := int64(*v)
|
|
nsec := int64((*v - float64(sec)) * 1e9)
|
|
t := time.Unix(sec, nsec).UTC()
|
|
return &t
|
|
}
|