p1.1: dynamic self-IP deny (DDNS/trace, keep previous, atomic swap)
Discover WAN via ddns:<host> then trace:<url> before listen. Persist to self_ip.json. Previous addresses stay denied for keep_previous. Failure keeps the last known set. /healthz reports age and source.
This commit is contained in:
+26
-15
@@ -18,6 +18,7 @@ import (
|
||||
"git.wntrmute.dev/kyle/sift/internal/clean"
|
||||
"git.wntrmute.dev/kyle/sift/internal/fetch"
|
||||
"git.wntrmute.dev/kyle/sift/internal/guard"
|
||||
"git.wntrmute.dev/kyle/sift/internal/selfip"
|
||||
)
|
||||
|
||||
const maxReqBody = 64 << 10
|
||||
@@ -30,6 +31,7 @@ type Server struct {
|
||||
Auth *auth.Store
|
||||
Mux *http.ServeMux
|
||||
OutCap int
|
||||
SelfIP *selfip.Discoverer
|
||||
|
||||
global chan struct{}
|
||||
perMu sync.Mutex
|
||||
@@ -80,30 +82,39 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (s *Server) healthz(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"status": "ok", "version": s.Version})
|
||||
out := map[string]any{"status": "ok", "version": s.Version}
|
||||
if s.SelfIP != nil {
|
||||
out["self_ip"] = s.SelfIP.Status()
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(out)
|
||||
}
|
||||
|
||||
func (s *Server) metrics(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
fails := uint64(0)
|
||||
if s.SelfIP != nil {
|
||||
fails = s.SelfIP.Failures.Load()
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"requests": s.reqN.Load(),
|
||||
"blocks": s.blockN.Load(),
|
||||
"scrapes": s.scrapeN.Load(),
|
||||
"requests": s.reqN.Load(),
|
||||
"blocks": s.blockN.Load(),
|
||||
"scrapes": s.scrapeN.Load(),
|
||||
"self_ip_failures": fails,
|
||||
})
|
||||
}
|
||||
|
||||
type scrapeReq struct {
|
||||
URL string `json:"url"`
|
||||
Formats []string `json:"formats"`
|
||||
OnlyMainContent *bool `json:"onlyMainContent"`
|
||||
SkipTlsVerification *bool `json:"skipTlsVerification"`
|
||||
RemoveBase64Images *bool `json:"removeBase64Images"`
|
||||
FastMode *bool `json:"fastMode"`
|
||||
BlockAds *bool `json:"blockAds"`
|
||||
StoreInCache *bool `json:"storeInCache"`
|
||||
MaxAge *int `json:"maxAge"`
|
||||
Mobile *bool `json:"mobile"`
|
||||
Origin string `json:"origin"`
|
||||
URL string `json:"url"`
|
||||
Formats []string `json:"formats"`
|
||||
OnlyMainContent *bool `json:"onlyMainContent"`
|
||||
SkipTlsVerification *bool `json:"skipTlsVerification"`
|
||||
RemoveBase64Images *bool `json:"removeBase64Images"`
|
||||
FastMode *bool `json:"fastMode"`
|
||||
BlockAds *bool `json:"blockAds"`
|
||||
StoreInCache *bool `json:"storeInCache"`
|
||||
MaxAge *int `json:"maxAge"`
|
||||
Mobile *bool `json:"mobile"`
|
||||
Origin string `json:"origin"`
|
||||
}
|
||||
|
||||
type v1Req struct {
|
||||
|
||||
Reference in New Issue
Block a user