mirror of
https://github.com/therootcompany/golib.git
synced 2026-04-24 20:58:00 +00:00
refactor: replace Username/Password with AuthHeader/AuthValue in httpcache
Generic header pair works for any auth scheme — Bearer, X-API-Key, Basic, etc. Auth is forwarded on redirects; the MaxMind-specific stripping is removed. geoip.go encodes Basic auth credentials directly into AuthValue.
This commit is contained in:
parent
d0a5e0a9d2
commit
3feb248ce1
@ -3,6 +3,7 @@ package geoip
|
|||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -50,14 +51,15 @@ func (d *Downloader) NewCacher(edition, path string) *httpcache.Cacher {
|
|||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
timeout = defaultTimeout
|
timeout = defaultTimeout
|
||||||
}
|
}
|
||||||
|
creds := base64.StdEncoding.EncodeToString([]byte(d.AccountID + ":" + d.LicenseKey))
|
||||||
return &httpcache.Cacher{
|
return &httpcache.Cacher{
|
||||||
URL: fmt.Sprintf("%s/%s/download?suffix=tar.gz", downloadBase, edition),
|
URL: fmt.Sprintf("%s/%s/download?suffix=tar.gz", downloadBase, edition),
|
||||||
Path: path,
|
Path: path,
|
||||||
MaxAge: time.Duration(freshDays) * 24 * time.Hour,
|
MaxAge: time.Duration(freshDays) * 24 * time.Hour,
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
Username: d.AccountID,
|
AuthHeader: "Authorization",
|
||||||
Password: d.LicenseKey,
|
AuthValue: "Basic " + creds,
|
||||||
Transform: ExtractMMDB,
|
Transform: ExtractMMDB,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,9 +37,9 @@ func (NopSyncer) Fetch() (bool, error) { return false, nil }
|
|||||||
// - MinInterval: skips if Fetch was called within this duration (in-memory).
|
// - MinInterval: skips if Fetch was called within this duration (in-memory).
|
||||||
// Guards against tight poll loops hammering a rate-limited API.
|
// Guards against tight poll loops hammering a rate-limited API.
|
||||||
//
|
//
|
||||||
// Auth — Username/Password sets HTTP Basic Auth on the initial request only.
|
// Auth — AuthHeader/AuthValue set a request header on every attempt, including
|
||||||
// The Authorization header is stripped before following any redirect, so
|
// redirects. Use any scheme: "Authorization"/"Bearer token",
|
||||||
// presigned redirect targets (e.g. Cloudflare R2) never receive credentials.
|
// "X-API-Key"/"secret", "Authorization"/"Basic base64(user:pass)", etc.
|
||||||
//
|
//
|
||||||
// Transform — if set, called with the response body instead of the default
|
// Transform — if set, called with the response body instead of the default
|
||||||
// atomic file copy. The func is responsible for writing to path atomically.
|
// atomic file copy. The func is responsible for writing to path atomically.
|
||||||
@ -51,8 +51,8 @@ type Cacher struct {
|
|||||||
Timeout time.Duration // 0 uses 5m; caps overall request including body read
|
Timeout time.Duration // 0 uses 5m; caps overall request including body read
|
||||||
MaxAge time.Duration // 0 disables; skip HTTP if file mtime is within this
|
MaxAge time.Duration // 0 disables; skip HTTP if file mtime is within this
|
||||||
MinInterval time.Duration // 0 disables; skip HTTP if last Fetch attempt was within this
|
MinInterval time.Duration // 0 disables; skip HTTP if last Fetch attempt was within this
|
||||||
Username string // Basic Auth — not forwarded on redirects
|
AuthHeader string // e.g. "Authorization" or "X-API-Key"
|
||||||
Password string
|
AuthValue string // e.g. "Bearer token" or "Basic base64(user:pass)"
|
||||||
Transform func(r io.Reader, path string) error // nil = direct atomic copy
|
Transform func(r io.Reader, path string) error // nil = direct atomic copy
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@ -116,23 +116,12 @@ func (c *Cacher) Fetch() (updated bool, err error) {
|
|||||||
TLSHandshakeTimeout: connTimeout,
|
TLSHandshakeTimeout: connTimeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
var client *http.Client
|
if c.AuthHeader != "" {
|
||||||
if c.Username != "" {
|
req.Header.Set(c.AuthHeader, c.AuthValue)
|
||||||
req.SetBasicAuth(c.Username, c.Password)
|
|
||||||
// Strip auth before following any redirect — presigned URLs (e.g. R2)
|
|
||||||
// must not receive our credentials.
|
|
||||||
client = &http.Client{
|
|
||||||
Timeout: timeout,
|
|
||||||
Transport: transport,
|
|
||||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
||||||
req.Header.Del("Authorization")
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
client = &http.Client{Timeout: timeout, Transport: transport}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: timeout, Transport: transport}
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user