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) } }