소스 검색

Proxify images defined in srcset attribute

Frédéric Guillot 5 년 전
부모
커밋
997006cdd7
2개의 변경된 파일83개의 추가작업 그리고 0개의 파일을 삭제
  1. 37 0
      template/functions.go
  2. 46 0
      template/functions_test.go

+ 37 - 0
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)))

+ 46 - 0
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 := `<p><img src="http://website/folder/image.png" srcset="http://website/folder/image2.png 656w, http://website/folder/image3.png 360w" alt="test"></p>`
+	expected := `<p><img src="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlLnBuZw==" srcset="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlMi5wbmc= 656w, /proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlMy5wbmc= 360w" alt="test"/></p>`
+	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 := `<picture><source srcset="http://website/folder/image2.png 656w, http://website/folder/image3.png 360w"></picture>`
+	expected := `<picture><source srcset="/proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlMi5wbmc= 656w, /proxy/aHR0cDovL3dlYnNpdGUvZm9sZGVyL2ltYWdlMy5wbmc= 360w"/></picture>`
+	output := imageProxyFilter(r, input)
+
+	if expected != output {
+		t.Errorf(`Not expected output: got %s`, output)
+	}
+}
+
 func TestFormatFileSize(t *testing.T) {
 	scenarios := []struct {
 		input    int64