mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-28 23:08:59 +02:00
fix(extensions): bound cookie runtime state
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package gobackend
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSimpleCookieJarReplacesAndExpiresCookies(t *testing.T) {
|
||||
jar, err := newSimpleCookieJar()
|
||||
if err != nil {
|
||||
t.Fatalf("newSimpleCookieJar: %v", err)
|
||||
}
|
||||
u, _ := url.Parse("https://api.example.com/path")
|
||||
|
||||
jar.SetCookies(u, []*http.Cookie{{Name: "session", Value: "old", Path: "/"}})
|
||||
jar.SetCookies(u, []*http.Cookie{{Name: "session", Value: "new", Path: "/"}})
|
||||
cookies := jar.Cookies(u)
|
||||
if len(cookies) != 1 || cookies[0].Value != "new" {
|
||||
t.Fatalf("replacement cookies = %#v", cookies)
|
||||
}
|
||||
|
||||
jar.SetCookies(u, []*http.Cookie{{
|
||||
Name: "session",
|
||||
Value: "expired",
|
||||
Path: "/",
|
||||
Expires: time.Now().Add(-time.Hour),
|
||||
MaxAge: -1,
|
||||
}})
|
||||
if cookies := jar.Cookies(u); len(cookies) != 0 {
|
||||
t.Fatalf("expired cookies = %#v", cookies)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleCookieJarClearAndScope(t *testing.T) {
|
||||
jar, err := newSimpleCookieJar()
|
||||
if err != nil {
|
||||
t.Fatalf("newSimpleCookieJar: %v", err)
|
||||
}
|
||||
apiURL, _ := url.Parse("https://api.example.com/private/resource")
|
||||
otherURL, _ := url.Parse("https://other.example.com/private/resource")
|
||||
publicURL, _ := url.Parse("https://api.example.com/public")
|
||||
|
||||
jar.SetCookies(apiURL, []*http.Cookie{{Name: "session", Value: "value", Path: "/private"}})
|
||||
if len(jar.Cookies(apiURL)) != 1 {
|
||||
t.Fatal("expected cookie for matching host and path")
|
||||
}
|
||||
if len(jar.Cookies(otherURL)) != 0 || len(jar.Cookies(publicURL)) != 0 {
|
||||
t.Fatal("cookie escaped its host or path scope")
|
||||
}
|
||||
|
||||
jar.Clear()
|
||||
if len(jar.Cookies(apiURL)) != 0 {
|
||||
t.Fatal("Clear retained cookies")
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -494,27 +495,36 @@ func isPrivateIPAddr(ip net.IP) bool {
|
||||
}
|
||||
|
||||
type simpleCookieJar struct {
|
||||
cookies map[string][]*http.Cookie
|
||||
mu sync.RWMutex
|
||||
mu sync.RWMutex
|
||||
jar *cookiejar.Jar
|
||||
}
|
||||
|
||||
func newSimpleCookieJar() (*simpleCookieJar, error) {
|
||||
return &simpleCookieJar{
|
||||
cookies: make(map[string][]*http.Cookie),
|
||||
}, nil
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &simpleCookieJar{jar: jar}, nil
|
||||
}
|
||||
|
||||
func (j *simpleCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
|
||||
j.mu.Lock()
|
||||
defer j.mu.Unlock()
|
||||
key := u.Host
|
||||
j.cookies[key] = append(j.cookies[key], cookies...)
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
j.jar.SetCookies(u, cookies)
|
||||
}
|
||||
|
||||
func (j *simpleCookieJar) Cookies(u *url.URL) []*http.Cookie {
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
return j.cookies[u.Host]
|
||||
return j.jar.Cookies(u)
|
||||
|
||||
}
|
||||
|
||||
func (j *simpleCookieJar) Clear() {
|
||||
jar, _ := cookiejar.New(nil)
|
||||
j.mu.Lock()
|
||||
j.jar = jar
|
||||
j.mu.Unlock()
|
||||
}
|
||||
|
||||
func (r *extensionRuntime) SetSettings(settings map[string]any) {
|
||||
|
||||
@@ -292,9 +292,7 @@ func (r *extensionRuntime) httpMethodShortcut(method string, call goja.FunctionC
|
||||
|
||||
func (r *extensionRuntime) httpClearCookies(call goja.FunctionCall) goja.Value {
|
||||
if jar, ok := r.cookieJar.(*simpleCookieJar); ok {
|
||||
jar.mu.Lock()
|
||||
jar.cookies = make(map[string][]*http.Cookie)
|
||||
jar.mu.Unlock()
|
||||
jar.Clear()
|
||||
GoLog("[Extension:%s] Cookies cleared\n", r.extensionID)
|
||||
return r.vm.ToValue(true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user