Просмотр исходного кода

Support proxying images

This should make it faster because the actual favicons are now cached,
too.  Especially over HTTP/2 connections, this should improve the
response times quite a bit.
Lucas Stadler лет назад: 9
Родитель
Сommit
6a9c715e4a
1 измененных файлов с 54 добавлено и 0 удалено
  1. 54 0
      go/favicon/favicon.go

+ 54 - 0
go/favicon/favicon.go

@ -4,6 +4,7 @@ import (
4 4
	"errors"
5 5
	"flag"
6 6
	"fmt"
7
	"io/ioutil"
7 8
	"net/http"
8 9
	"net/url"
9 10
	"os"
@ -21,12 +22,17 @@ var debug = flag.Bool("debug", false, "Print out debug info")
21 22
var faviconCache *lru.Cache
22 23
var lock sync.RWMutex
23 24
25
var imageCache *lru.Cache
26
var imageLock sync.RWMutex
27
24 28
func main() {
25 29
	flag.Parse()
26 30
27 31
	faviconCache = lru.New(*cacheSize)
32
	imageCache = lru.New(*cacheSize)
28 33
29 34
	http.HandleFunc("/favicon", HandleGetFavicon)
35
	http.HandleFunc("/favicon_proxy", HandleProxy)
30 36
	if p := os.Getenv("PORT"); p != "" {
31 37
		flag.Set("p", p)
32 38
	}
@ -40,6 +46,54 @@ func main() {
40 46
	}
41 47
}
42 48
49
func HandleProxy(w http.ResponseWriter, r *http.Request) {
50
	url := r.URL.Query()["url"][0]
51
	favicon, err := GetFaviconCached(url)
52
	if err != nil {
53
		fmt.Printf("Error: '%s': %s\n", url, err)
54
		w.WriteHeader(http.StatusNotFound)
55
		w.Write([]byte(fmt.Sprint(err)))
56
		return
57
	}
58
59
	image, err := GetImageCached(favicon)
60
	if err != nil {
61
		fmt.Printf("Error: '%s': %s\n", url, err)
62
		w.WriteHeader(http.StatusNotFound)
63
		w.Write([]byte(fmt.Sprint(err)))
64
		return
65
	}
66
67
	w.Write(image)
68
}
69
70
func GetImageCached(u string) ([]byte, error) {
71
	imageLock.RLock()
72
	image, cached := imageCache.Get(u)
73
	imageLock.RUnlock()
74
75
	if cached {
76
		return image.([]byte), nil
77
	}
78
79
	resp, err := http.Get(u)
80
	if err != nil {
81
		return nil, err
82
	}
83
	defer resp.Body.Close()
84
85
	imageData, err := ioutil.ReadAll(resp.Body)
86
	if err != nil {
87
		return nil, err
88
	}
89
90
	imageLock.Lock()
91
	imageCache.Add(u, imageData)
92
	imageLock.Unlock()
93
	return imageData, nil
94
95
}
96
43 97
func HandleGetFavicon(w http.ResponseWriter, r *http.Request) {
44 98
	url := r.URL.Query()["url"][0]
45 99
	favicon, err := GetFaviconCached(url)