marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

commit 618b9ef38b861f92769a5ab15e484d03710b6be3
parent 16e579a2e440dd6fe9b404365dc69f600c63c089
Author: David Eisinger <[email protected]>
Date:   Fri, 10 Oct 2025 21:01:49 -0400

Fix bookshop.org error

Diffstat:
M.gitignore | 1+
Minternal/api.go | 11+++++++++++
Minternal/archiver.go | 11+++++++++--
3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,4 @@ bin coverage.out dist +scripts diff --git a/internal/api.go b/internal/api.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "os" + "os/exec" "path" "strconv" "strings" @@ -505,6 +506,16 @@ func NewHandlerWithConfig(db *DB, cfg HandlerConfig) (http.Handler, error) { if isHTML { fetchedTitle, txt, err = TitleAndText(ctx, req.URL) if err != nil { + // Fallback: if HTML fetch fails, try w3m directly to get plaintext + if path, err2 := exec.LookPath("w3m"); err2 == nil && path != "" { + if out, err3 := w3mDump(ctx, req.URL); err3 == nil && strings.TrimSpace(out) != "" { + txt = strings.TrimSpace(out) + fetchedTitle = "" + err = nil + } + } + } + if err != nil { http.Error(w, "failed to archive URL", http.StatusBadGateway) return } diff --git a/internal/archiver.go b/internal/archiver.go @@ -48,6 +48,9 @@ func TitleAndText(ctx context.Context, rawURL string) (string, string, error) { return title, txt, nil } +// browserUA is a conservative desktop browser User-Agent that passes common bot checks. +const browserUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:128.0) Gecko/20100101 Firefox/128.0" + // IsHTMLURL attempts a HEAD request and inspects Content-Type to determine if // the resource is HTML. If Content-Type is empty or HEAD fails, we assume HTML // to avoid false negatives on servers that mishandle HEAD. @@ -56,7 +59,9 @@ func IsHTMLURL(ctx context.Context, rawURL string) bool { if err != nil { return true } - req.Header.Set("User-Agent", "marky-archiver/1.0 (+https://example.invalid)") + req.Header.Set("User-Agent", browserUA) + req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + req.Header.Set("Accept-Language", "en-US,en;q=0.9") client := &http.Client{Timeout: 15 * time.Second} resp, err := client.Do(req) if err != nil { @@ -89,7 +94,9 @@ func fetchHTML(ctx context.Context, rawURL string) ([]byte, error) { if err != nil { return nil, fmt.Errorf("build request: %w", err) } - req.Header.Set("User-Agent", "marky-archiver/1.0 (+https://example.invalid)") + req.Header.Set("User-Agent", browserUA) + req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + req.Header.Set("Accept-Language", "en-US,en;q=0.9") client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req)