src/go/plugin/go.d/modules/httpcheck/cookiejar.go
// SPDX-License-Identifier: GPL-3.0-or-later
package httpcheck
import (
"bufio"
"fmt"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"strconv"
"strings"
"time"
"golang.org/x/net/publicsuffix"
)
// TODO: implement proper cookie auth support
// relevant forum topic: https://community.netdata.cloud/t/howto-http-endpoint-collector-with-cookie-and-user-pass/3981/5?u=ilyam8
// cookie file format: https://everything.curl.dev/http/cookies/fileformat
func loadCookieJar(path string) (http.CookieJar, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer func() { _ = file.Close() }()
jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
if err != nil {
return nil, err
}
sc := bufio.NewScanner(file)
for sc.Scan() {
line, httpOnly := strings.CutPrefix(strings.TrimSpace(sc.Text()), "#HttpOnly_")
if strings.HasPrefix(line, "#") || line == "" {
continue
}
parts := strings.Fields(line)
if len(parts) != 6 && len(parts) != 7 {
return nil, fmt.Errorf("got %d fields in line '%s', want 6 or 7", len(parts), line)
}
for i, v := range parts {
parts[i] = strings.TrimSpace(v)
}
cookie := &http.Cookie{
Domain: parts[0],
Path: parts[2],
Name: parts[5],
HttpOnly: httpOnly,
}
cookie.Secure, err = strconv.ParseBool(parts[3])
if err != nil {
return nil, err
}
expires, err := strconv.ParseInt(parts[4], 10, 64)
if err != nil {
return nil, err
}
if expires > 0 {
cookie.Expires = time.Unix(expires, 0)
}
if len(parts) == 7 {
cookie.Value = parts[6]
}
scheme := "http"
if cookie.Secure {
scheme = "https"
}
cookieURL := &url.URL{
Scheme: scheme,
Host: cookie.Domain,
}
cookies := jar.Cookies(cookieURL)
cookies = append(cookies, cookie)
jar.SetCookies(cookieURL, cookies)
}
return jar, nil
}