127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package httpdl
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestParseNetscapeCookie(t *testing.T) {
|
|
future := time.Now().Add(24 * time.Hour).Unix()
|
|
tests := []struct {
|
|
name string
|
|
line string
|
|
wantNil bool
|
|
wantName string
|
|
wantValue string
|
|
wantDom string // expected http.Cookie.Domain (empty for host-only)
|
|
wantHTTP bool
|
|
}{
|
|
{
|
|
name: "domain cookie",
|
|
line: ".example.com\tTRUE\t/\tFALSE\t" + itoa(future) + "\tSID\tabc123",
|
|
wantName: "SID",
|
|
wantValue: "abc123",
|
|
wantDom: ".example.com",
|
|
},
|
|
{
|
|
name: "host-only cookie",
|
|
line: "example.com\tFALSE\t/\tTRUE\t" + itoa(future) + "\ttoken\txyz",
|
|
wantName: "token",
|
|
wantValue: "xyz",
|
|
wantDom: "", // host-only: no Domain attribute
|
|
},
|
|
{
|
|
name: "httponly prefix kept",
|
|
line: "#HttpOnly_example.com\tFALSE\t/\tFALSE\t" + itoa(future) + "\tHO\tsecret",
|
|
wantName: "HO",
|
|
wantValue: "secret",
|
|
wantHTTP: true,
|
|
},
|
|
{
|
|
name: "empty value field",
|
|
line: "example.com\tFALSE\t/\tFALSE\t0\tflag\t",
|
|
wantName: "flag",
|
|
wantValue: "",
|
|
},
|
|
{
|
|
name: "comment line",
|
|
line: "# this is a comment",
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "blank line",
|
|
line: " ",
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "too few fields",
|
|
line: "example.com\tFALSE\t/\tFALSE\t0",
|
|
wantNil: true,
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c, u := parseNetscapeCookie(tc.line)
|
|
if tc.wantNil {
|
|
if c != nil {
|
|
t.Fatalf("expected nil cookie, got %+v", c)
|
|
}
|
|
return
|
|
}
|
|
if c == nil {
|
|
t.Fatal("expected a cookie, got nil")
|
|
}
|
|
if c.Name != tc.wantName || c.Value != tc.wantValue {
|
|
t.Fatalf("name/value = %q/%q, want %q/%q", c.Name, c.Value, tc.wantName, tc.wantValue)
|
|
}
|
|
if c.Domain != tc.wantDom {
|
|
t.Fatalf("domain = %q, want %q", c.Domain, tc.wantDom)
|
|
}
|
|
if c.HttpOnly != tc.wantHTTP {
|
|
t.Fatalf("httponly = %v, want %v", c.HttpOnly, tc.wantHTTP)
|
|
}
|
|
if u == nil {
|
|
t.Fatal("expected a URL, got nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func itoa(n int64) string { return strconv.FormatInt(n, 10) }
|
|
func itoa64(n int64) string { return strconv.FormatInt(n, 10) }
|
|
|
|
func TestLoadCookieJarMissingFile(t *testing.T) {
|
|
// A missing cookies file is not an error: there are simply no cookies to load.
|
|
jar, err := loadCookieJar(filepath.Join(t.TempDir(), "nope.txt"))
|
|
if err != nil {
|
|
t.Fatalf("missing file should not error: %v", err)
|
|
}
|
|
if jar == nil {
|
|
t.Fatal("expected an empty jar, got nil")
|
|
}
|
|
}
|
|
|
|
func TestLoadCookieJarAppliesCookie(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "cookies.txt")
|
|
future := time.Now().Add(24 * time.Hour).Unix()
|
|
data := "# Netscape HTTP Cookie File\n" +
|
|
".example.com\tTRUE\t/\tFALSE\t" + itoa64(future) + "\tSID\tabc123\n"
|
|
if err := os.WriteFile(path, []byte(data), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
jar, err := loadCookieJar(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
req, _ := http.NewRequest(http.MethodGet, "http://www.example.com/file", nil)
|
|
got := jar.Cookies(req.URL)
|
|
if len(got) != 1 || got[0].Name != "SID" || got[0].Value != "abc123" {
|
|
t.Fatalf("jar did not apply the domain cookie to a subdomain: %+v", got)
|
|
}
|
|
}
|