commit 21079b0

delthas  ·  2026-03-19 16:12:57 +0000 UTC
parent f2011e8
Set User-Agent header in fetchImage HTTP requests

Image fetching timed out on some hosts (e.g. catbox.moe) because Go's
default HTTP client sends "Go-http-client/2.0" as the User-Agent when
HTTP/2 is negotiated, which certain servers silently block by never
sending response headers.

Set a "senpai/<version>" (or "senpai") User-Agent on all HTTP requests
in fetchImage (HEAD, HTML GET, and image GET). Also close the HEAD
response body and fix minor whitespace.

Fixes: https://todo.sr.ht/~delthas/senpai/230
1 files changed,  +21, -4
M app.go
M app.go
+21, -4
 1@@ -243,7 +243,7 @@ func NewApp(cfg Config) (app *App, err error) {
 2 }
 3 
 4 func (app *App) Close() {
 5-	app.win.Exit()       // tell all instances of app.ircLoop to stop when possible
 6+	app.win.Exit() // tell all instances of app.ircLoop to stop when possible
 7 	app.postEvent(event{ // tell app.eventLoop to stop
 8 		src:     "*",
 9 		content: nil,
10@@ -1204,6 +1204,11 @@ var patternOpenGraphImage = regexp.MustCompile(`<meta property="og:image" conten
11 var patternOpenGraphVideo = regexp.MustCompile(`<meta property="og:video"`)
12 
13 func (app *App) fetchImage(link string) (image.Image, error) {
14+	userAgent := "senpai"
15+	if v, ok := BuildVersion(); ok {
16+		userAgent = "senpai/" + v
17+	}
18+
19 	if u, err := url.Parse(link); err == nil {
20 		changed := true
21 		switch u.Host {
22@@ -1220,10 +1225,16 @@ func (app *App) fetchImage(link string) (image.Image, error) {
23 	cHead := http.Client{
24 		Timeout: 1500 * time.Millisecond,
25 	}
26-	res, err := cHead.Head(link)
27+	req, err := http.NewRequest("HEAD", link, nil)
28+	if err != nil {
29+		return nil, err
30+	}
31+	req.Header.Set("User-Agent", userAgent)
32+	res, err := cHead.Do(req)
33 	if err != nil {
34 		return nil, err
35 	}
36+	res.Body.Close()
37 	if res.StatusCode != http.StatusOK {
38 		return nil, fmt.Errorf("unexpected status code: %d", res.StatusCode)
39 	}
40@@ -1244,11 +1255,12 @@ func (app *App) fetchImage(link string) (image.Image, error) {
41 		if err != nil {
42 			return nil, err
43 		}
44+		req.Header.Set("User-Agent", userAgent)
45 		var previewSize int64 = 10 * 1024
46 		if res.Header.Get("Accept-Ranges") == "bytes" {
47 			req.Header.Set("Range", fmt.Sprintf("bytes=0-%v", previewSize))
48 		}
49-		res, err = cHead.Get(link)
50+		res, err = cHead.Do(req)
51 		if err != nil {
52 			return nil, err
53 		}
54@@ -1270,7 +1282,12 @@ func (app *App) fetchImage(link string) (image.Image, error) {
55 	cGet := http.Client{
56 		Timeout: 5 * time.Second,
57 	}
58-	res, err = cGet.Get(link)
59+	req, err = http.NewRequest("GET", link, nil)
60+	if err != nil {
61+		return nil, err
62+	}
63+	req.Header.Set("User-Agent", userAgent)
64+	res, err = cGet.Do(req)
65 	if err != nil {
66 		return nil, err
67 	}