From 997006cdd707ac59a3cb59870cec0008ab408a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Wed, 7 Oct 2020 21:57:18 -0700 Subject: [PATCH] Proxify images defined in srcset attribute --- template/functions.go | 37 ++++++++++++++++++++++++++++++ template/functions_test.go | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/template/functions.go b/template/functions.go index 77e22e95..6914d096 100644 --- a/template/functions.go +++ b/template/functions.go @@ -200,12 +200,49 @@ func imageProxyFilter(router *mux.Router, data string) string { img.SetAttr("src", proxify(router, srcAttr)) } } + + if srcsetAttr, ok := img.Attr("srcset"); ok { + if proxyImages == "all" || !url.IsHTTPS(srcsetAttr) { + proxifySourceSet(img, router, srcsetAttr) + } + } + }) + + doc.Find("picture source").Each(func(i int, sourceElement *goquery.Selection) { + if srcsetAttr, ok := sourceElement.Attr("srcset"); ok { + if proxyImages == "all" || !url.IsHTTPS(srcsetAttr) { + proxifySourceSet(sourceElement, router, srcsetAttr) + } + } }) output, _ := doc.Find("body").First().Html() return output } +func proxifySourceSet(element *goquery.Selection, router *mux.Router, attributeValue string) { + var proxifiedSources []string + + for _, source := range strings.Split(attributeValue, ",") { + parts := strings.Split(strings.TrimSpace(source), " ") + nbParts := len(parts) + + if nbParts > 0 { + source = proxify(router, parts[0]) + + if nbParts > 1 { + source += " " + parts[1] + } + + proxifiedSources = append(proxifiedSources, source) + } + } + + if len(proxifiedSources) > 0 { + element.SetAttr("srcset", strings.Join(proxifiedSources, ", ")) + } +} + func proxify(router *mux.Router, link string) string { // We use base64 url encoding to avoid slash in the URL. return route.Path(router, "proxy", "encodedURL", base64.URLEncoding.EncodeToString([]byte(link))) diff --git a/template/functions_test.go b/template/functions_test.go index 4f1ec083..1b327bea 100644 --- a/template/functions_test.go +++ b/template/functions_test.go @@ -315,6 +315,52 @@ func TestProxyFilterWithHttpsInvalid(t *testing.T) { } } +func TestProxyFilterWithSrcset(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "all") + + var err error + parser := config.NewParser() + config.Opts, err = parser.ParseEnvironmentVariables() + if err != nil { + t.Fatalf(`Parsing failure: %v`, err) + } + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `

test

` + expected := `

test

` + output := imageProxyFilter(r, input) + + if expected != output { + t.Errorf(`Not expected output: got %s`, output) + } +} + +func TestProxyFilterWithPictureSource(t *testing.T) { + os.Clearenv() + os.Setenv("PROXY_IMAGES", "all") + + var err error + parser := config.NewParser() + config.Opts, err = parser.ParseEnvironmentVariables() + if err != nil { + t.Fatalf(`Parsing failure: %v`, err) + } + + r := mux.NewRouter() + r.HandleFunc("/proxy/{encodedURL}", func(w http.ResponseWriter, r *http.Request) {}).Name("proxy") + + input := `` + expected := `` + output := imageProxyFilter(r, input) + + if expected != output { + t.Errorf(`Not expected output: got %s`, output) + } +} + func TestFormatFileSize(t *testing.T) { scenarios := []struct { input int64