diff --git a/config/config.go b/config/config.go index 3cb2ef29c60e770723baed0e114df42308678065..4cba789579a525521d1737ba5e20a14ee0417eeb 100644 --- a/config/config.go +++ b/config/config.go @@ -26,6 +26,7 @@ const ( defaultCertDomain = "" defaultCertCache = "/tmp/cert_cache" defaultCleanupFrequency = 24 + defaultProxyImages = "http-only" ) // Config manages configuration parameters. @@ -217,6 +218,11 @@ func (c *Config) PocketConsumerKey(defaultValue string) string { return c.get("POCKET_CONSUMER_KEY", defaultValue) } +// ProxyImages returns "none" to never proxy, "http-only" to proxy non-HTTPS, "all" to always proxy. +func (c *Config) ProxyImages() string { + return c.get("PROXY_IMAGES", defaultProxyImages) +} + // NewConfig returns a new Config. func NewConfig() *Config { cfg := &Config{ diff --git a/filter/image_proxy_filter.go b/filter/image_proxy_filter.go index ef6d39733b09f304a3dc35264942ba6885fd5612..99884e375528894245fe4fb70f4a861c785f2bfc 100644 --- a/filter/image_proxy_filter.go +++ b/filter/image_proxy_filter.go @@ -8,6 +8,7 @@ import ( "encoding/base64" "strings" + "github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/http/route" "github.com/miniflux/miniflux/url" @@ -15,8 +16,13 @@ import ( "github.com/gorilla/mux" ) -// ImageProxyFilter rewrites image tag URLs without HTTPS to local proxy URL -func ImageProxyFilter(router *mux.Router, data string) string { +// ImageProxyFilter rewrites image tag URLs to local proxy URL (by default only non-HTTPS URLs) +func ImageProxyFilter(router *mux.Router, cfg *config.Config, data string) string { + proxyImages := cfg.ProxyImages() + if proxyImages == "none" { + return data + } + doc, err := goquery.NewDocumentFromReader(strings.NewReader(data)) if err != nil { return data @@ -24,7 +30,7 @@ func ImageProxyFilter(router *mux.Router, data string) string { doc.Find("img").Each(func(i int, img *goquery.Selection) { if srcAttr, ok := img.Attr("src"); ok { - if !url.IsHTTPS(srcAttr) { + if proxyImages == "all" || !url.IsHTTPS(srcAttr) { img.SetAttr("src", Proxify(router, srcAttr)) } } diff --git a/filter/image_proxy_filter_test.go b/filter/image_proxy_filter_test.go index 992516eb06d4a2000664151c30f59ac5c28598aa..7c1376ed348e23769722de6cfeb59d226019e808 100644 --- a/filter/image_proxy_filter_test.go +++ b/filter/image_proxy_filter_test.go @@ -6,17 +6,126 @@ package filter import ( "net/http" + "os" "testing" + "github.com/miniflux/miniflux/config" + "github.com/gorilla/mux" ) -func TestProxyFilterWithHttp(t *testing.T) { +func TestProxyFilterWithHttpDefault(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "http-only") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="http://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := `<p><img src="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlLnBuZw==" alt="Test"/></p>` + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpsDefault(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "http-only") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpNever(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "none") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="http://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := input + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpsNever(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "none") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := input + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpAlways(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "all") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="http://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := `<p><img src="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlLnBuZw==" alt="Test"/></p>` + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpsAlways(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "all") + c := config.NewConfig() + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` + output := ImageProxyFilter(r, c, input) + expected := `<p><img src="/proxy/aHR0cHM6Ly93ZWJzaXRlL2ZvbGRlci9pbWFnZS5wbmc=" alt="Test"/></p>` + + if expected != output { + t.Errorf(`Not expected output: got "%s" instead of "%s"`, output, expected) + } +} + +func TestProxyFilterWithHttpInvalid(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "invalid") + c := config.NewConfig() + r := mux.NewRouter() r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") input := `<p><img src="http://website/folder/image.png" alt="Test"/></p>` - output := ImageProxyFilter(r, input) + output := ImageProxyFilter(r, c, input) expected := `<p><img src="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlLnBuZw==" alt="Test"/></p>` if expected != output { @@ -24,12 +133,16 @@ func TestProxyFilterWithHttp(t *testing.T) { } } -func TestProxyFilterWithHttps(t *testing.T) { +func TestProxyFilterWithHttpsInvalid(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "invalid") + c := config.NewConfig() + r := mux.NewRouter() r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") input := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` - output := ImageProxyFilter(r, input) + output := ImageProxyFilter(r, c, input) expected := `<p><img src="https://website/folder/image.png" alt="Test"/></p>` if expected != output { diff --git a/template/functions.go b/template/functions.go index e80a4a52a1b6baa43d4e215a3510ffd1d7155989..f68d6fb7aeed5cae9353ebc86d858948a0c5dfbb 100644 --- a/template/functions.go +++ b/template/functions.go @@ -46,14 +46,16 @@ func (f *funcMap) Map() template.FuncMap { return template.HTML(str) }, "proxyFilter": func(data string) string { - return filter.ImageProxyFilter(f.router, data) + return filter.ImageProxyFilter(f.router, f.cfg, data) }, "proxyURL": func(link string) string { - if url.IsHTTPS(link) { - return link + proxyImages := f.cfg.ProxyImages() + + if proxyImages == "all" || (proxyImages != "none" && !url.IsHTTPS(link)) { + return filter.Proxify(f.router, link) } - return filter.Proxify(f.router, link) + return link }, "domain": func(websiteURL string) string { return url.Domain(websiteURL)