p2: fence document tags, atomic fleetctx, harden workspace

Neutralise </document and <document in page text. Counters are
atomic.Uint64. Workspace names are [A-Za-z0-9_-] and PathEscaped;
foreign workspace_id rows are dropped. Wayback closest.url must be
https://web.archive.org. archive.today snapshot_at is Memento-Datetime
or null.
This commit is contained in:
2026-09-23 00:01:04 -07:00
parent 2f9d3d97e6
commit ff87a04f94
8 changed files with 149 additions and 17 deletions
+13 -2
View File
@@ -9,7 +9,6 @@ import (
"net/url"
"regexp"
"strings"
"time"
"git.wntrmute.dev/kyle/sift/internal/fetch"
)
@@ -75,6 +74,10 @@ func wayback(ctx context.Context, f Fetcher, original string) (*Result, error) {
if !c.Available || c.URL == "" {
return nil, fmt.Errorf("wayback: unavailable")
}
u, err := url.Parse(c.URL)
if err != nil || u.Scheme != "https" || strings.ToLower(u.Hostname()) != "web.archive.org" {
return nil, fmt.Errorf("wayback: bad snapshot url")
}
snapURL := insertID(c.URL)
page, err := f.Fetch(ctx, snapURL)
if err != nil {
@@ -122,7 +125,8 @@ func archiveToday(ctx context.Context, f Fetcher, original string) (*Result, err
last = fmt.Errorf("archive.today: fake success")
continue
}
return &Result{Res: res, Via: ViaToday, SnapshotAt: res.FetchedAt.UTC().Format(time.RFC3339), OriginalURL: original}, nil
at := mementoDatetime(res)
return &Result{Res: res, Via: ViaToday, SnapshotAt: at, OriginalURL: original}, nil
}
if last == nil {
last = fmt.Errorf("archive.today: exhausted")
@@ -162,6 +166,13 @@ func bytesTrim(b []byte) []byte {
return []byte(strings.TrimSpace(string(b)))
}
func mementoDatetime(res *fetch.Resource) string {
if res == nil || res.Header == nil {
return ""
}
return strings.TrimSpace(res.Header.Get("Memento-Datetime"))
}
func hostOf(raw string) string {
u, err := url.Parse(raw)
if err != nil {