Documentation ¶
Overview ¶
Package kooky contains routines to reach into cookie stores for various browsers and retrieve the cookies.
Example (ChromeSimpleMacOS) ¶
package main import ( "fmt" "os" "github.com/etng/kooky/browser/chrome" ) // on macOS: var cookieStorePath = "/Google/Chrome/Default/Cookies" func main() { // construct file path for the sqlite database containing the cookies dir, _ := os.UserConfigDir() // on macOS: "/<USER>/Library/Application Support/" cookieStoreFile := dir + cookieStorePath // read the cookies from the file // decryption is handled automatically cookies, err := chrome.ReadCookies(cookieStoreFile) if err != nil { // TODO: handle the error return } for _, cookie := range cookies { fmt.Println(cookie) } }
Output:
Example (CookieJar) ¶
package main import ( "fmt" "io" "log" "net/http" "net/url" "strings" "github.com/etng/kooky" _ "github.com/etng/kooky/browser/firefox" ) func main() { stores := kooky.FindAllCookieStores() var s kooky.CookieStore for _, store := range stores { if store.Browser() != `firefox` || !store.IsDefaultProfile() { continue } s = store break } // jar := s // only store cookies relevant for the target website in the cookie jar jar, _ := s.SubJar(kooky.Domain(`github.com`)) u, _ := url.Parse(`https://github.com/settings/profile`) var loggedIn bool cookies := kooky.FilterCookies(jar.Cookies(u), kooky.Name(`logged_in`)) if len(cookies) > 0 { loggedIn = true } if !loggedIn { log.Fatal(`not logged in`) } client := http.Client{Jar: jar} resp, _ := client.Get(u.String()) body, _ := io.ReadAll(resp.Body) if !strings.Contains(string(body), `id="user_profile_name"`) { fmt.Print("not ") } fmt.Println("logged in") }
Output: logged in
Index ¶
- func ExportCookies[T Cookie | http.Cookie](w io.Writer, cookies []*T)
- func FilterCookie[T Cookie | http.Cookie](cookie *T, filters ...Filter) bool
- func FilterCookies[T Cookie | http.Cookie](cookies []*T, filters ...Filter) []*T
- func RegisterFinder(browser string, finder CookieStoreFinder)
- type Cookie
- type CookieStore
- type CookieStoreFinder
- type Filter
- func CreationAfter(u time.Time) Filter
- func CreationBefore(u time.Time) Filter
- func Domain(domain string) Filter
- func DomainContains(substr string) Filter
- func DomainHasPrefix(prefix string) Filter
- func DomainHasSuffix(suffix string) Filter
- func ExpiresAfter(u time.Time) Filter
- func ExpiresBefore(u time.Time) Filter
- func Name(name string) Filter
- func NameContains(substr string) Filter
- func NameHasPrefix(prefix string) Filter
- func NameHasSuffix(suffix string) Filter
- func Path(path string) Filter
- func PathContains(substr string) Filter
- func PathDepth(depth int) Filter
- func PathHasPrefix(prefix string) Filter
- func PathHasSuffix(suffix string) Filter
- func Value(value string) Filter
- func ValueContains(substr string) Filter
- func ValueHasPrefix(prefix string) Filter
- func ValueHasSuffix(suffix string) Filter
- func ValueLen(length int) Filter
- type FilterFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExportCookies ¶
ExportCookies() export "cookies" in the Netscape format.
curl, wget, ... use this format.
Example ¶
package main import ( "net/http" "os" "github.com/etng/kooky" ) var cookieFile = `cookies.txt` func main() { var cookies = []*kooky.Cookie{{Cookie: http.Cookie{Domain: `.test.com`, Name: `test`, Value: `dGVzdA==`}}} file, err := os.OpenFile(cookieFile, os.O_RDWR|os.O_CREATE, 0644) if err != nil { // TODO: handle error return } defer file.Close() kooky.ExportCookies(file, cookies) }
Output:
func FilterCookie ¶
FilterCookie() tells if a "cookie" passes all "filters".
func FilterCookies ¶
FilterCookies() applies "filters" in order to the "cookies".
Example ¶
package main import ( "github.com/etng/kooky" _ "github.com/etng/kooky/browser/all" // register cookiestore finders ) var cookieName = `NID` func main() { cookies := kooky.ReadCookies() // automatic read cookies = kooky.FilterCookies( cookies, kooky.Valid, // remove expired cookies kooky.DomainContains(`google`), // cookie domain has to contain "google" kooky.Name(cookieName), // cookie name is "NID" kooky.Debug, // print cookies after applying previous filter ) }
Output:
func RegisterFinder ¶
func RegisterFinder(browser string, finder CookieStoreFinder)
RegisterFinder() registers CookieStoreFinder enabling automatic finding of cookie stores with FindAllCookieStores() and ReadCookies().
RegisterFinder() is called by init() in the browser subdirectories.
Types ¶
type Cookie ¶
Cookie is the struct returned by functions in this package. Similar to http.Cookie.
func ReadCookies ¶
ReadCookies() uses registered cookiestore finders to read cookies. Erronous reads are skipped.
Register cookie store finders for all browsers like this:
import _ "github.com/etng/kooky/browser/all"
Or only a specific browser:
import _ "github.com/etng/kooky/browser/chrome"
Example (All) ¶
package main import ( "fmt" "github.com/etng/kooky" _ "github.com/etng/kooky/browser/all" // This registers all cookiestore finders! // _ "github.com/etng/kooky/browser/chrome" // load only the chrome cookiestore finder ) func main() { // try to find cookie stores in default locations and // read the cookies from them. // decryption is handled automatically. cookies := kooky.ReadCookies() for _, cookie := range cookies { fmt.Println(cookie) } } var _ struct{} // ignore this - for correct working of the documentation tool
Output:
type CookieStore ¶
type CookieStore interface { http.CookieJar SubJar(filters ...Filter) (http.CookieJar, error) ReadCookies(...Filter) ([]*Cookie, error) Browser() string Profile() string IsDefaultProfile() bool FilePath() string Close() error }
CookieStore represents a file, directory, etc containing cookies.
Call CookieStore.Close() after using any of its methods.
func FindAllCookieStores ¶
func FindAllCookieStores() []CookieStore
FindAllCookieStores() tries to find cookie stores at default locations.
FindAllCookieStores() requires registered CookieStoreFinders.
Register cookie store finders for all browsers like this:
import _ "github.com/etng/kooky/browser/all"
Or only a specific browser:
import _ "github.com/etng/kooky/browser/chrome"
Example ¶
package main import ( "fmt" "github.com/etng/kooky" _ "github.com/etng/kooky/browser/all" ) func main() { cookieStores := kooky.FindAllCookieStores() for _, store := range cookieStores { // CookieStore keeps files/databases open for repeated reads // close those when no longer needed defer store.Close() var filters = []kooky.Filter{ kooky.Valid, // remove expired cookies } cookies, _ := store.ReadCookies(filters...) for _, cookie := range cookies { fmt.Printf( "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", store.Browser(), store.Profile(), store.FilePath(), cookie.Domain, cookie.Name, cookie.Value, cookie.Expires.Format(`2006.01.02 15:04:05`), ) } } }
Output:
type CookieStoreFinder ¶
type CookieStoreFinder interface {
FindCookieStores() ([]CookieStore, error)
}
CookieStoreFinder tries to find cookie stores at default locations.
type Filter ¶
Filter is used for filtering cokies in ReadCookies() functions.
A cookie passes the Filter if Filter.Filter returns true.
Example (Regex) ¶
package main import ( "fmt" "net/http" "regexp" "github.com/etng/kooky" ) // example regex matching base64 strings var reBase64 = regexp.MustCompile(`^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$`) func main() { var cookies = []*kooky.Cookie{{Cookie: http.Cookie{Name: `test`, Value: `dGVzdA==`}}} cookies = kooky.FilterCookies( cookies, ValueRegexMatch(reBase64), // filter cookies with the regex filter // kooky.Debug, // print cookies after applying the regex filter ) for _, cookie := range cookies { fmt.Println(cookie.Value) break // only first element } } func ValueRegexMatch(re *regexp.Regexp) kooky.Filter { return kooky.FilterFunc(func(cookie *kooky.Cookie) bool { return cookie != nil && re != nil && re.Match([]byte(cookie.Value)) }) }
Output: dGVzdA==
var Debug Filter = FilterFunc(func(cookie *Cookie) bool { fmt.Printf("%+#v\n", cookie) return true })
Debug prints the cookie.
Position Debug after the filter you want to test.
var HTTPOnly Filter = FilterFunc(func(cookie *Cookie) bool { return cookie != nil && cookie.HttpOnly })
var Secure Filter = FilterFunc(func(cookie *Cookie) bool { return cookie != nil && cookie.Secure })
func CreationAfter ¶
func CreationBefore ¶
func DomainContains ¶
func DomainHasPrefix ¶
func DomainHasSuffix ¶
func ExpiresAfter ¶
func ExpiresBefore ¶
func NameContains ¶
func NameHasPrefix ¶
func NameHasSuffix ¶
func PathContains ¶
func PathHasPrefix ¶
func PathHasSuffix ¶
func ValueContains ¶
func ValueHasPrefix ¶
func ValueHasSuffix ¶
type FilterFunc ¶
func (FilterFunc) Filter ¶
func (f FilterFunc) Filter(c *Cookie) bool