diff --git a/proxy/portal/logo_provider.go b/proxy/portal/logo_provider.go index 9cf63e360..d42b7d090 100644 --- a/proxy/portal/logo_provider.go +++ b/proxy/portal/logo_provider.go @@ -118,12 +118,12 @@ func (p *faviconDiscoveryLogoProvider) discoverLogoURL(ctx context.Context, rawU // look for any logos in the html r := io.LimitReader(res.Body, 10*1024) for link := range findIconLinksInHTML(r) { - linkURL, err := urlutil.ParseAndValidateURL(link) + linkURL, err := u.Parse(link) if err != nil { continue } - logoURL := p.fetchLogoURL(ctx, c, u.ResolveReference(linkURL)) + logoURL := p.fetchLogoURL(ctx, c, linkURL) if logoURL != "" { return logoURL, nil } @@ -200,7 +200,7 @@ func findIconLinksInHTML(r io.Reader) iter.Seq[string] { } switch tt { - case html.StartTagToken: + case html.StartTagToken, html.SelfClosingTagToken: name, attr := parseTag(z) if name == "link" && attr["href"] != "" && (attr["rel"] == "shortcut icon" || attr["rel"] == "icon") { if !yield(attr["href"]) { diff --git a/proxy/portal/logo_provider_test.go b/proxy/portal/logo_provider_test.go index 28d35723d..a14244b06 100644 --- a/proxy/portal/logo_provider_test.go +++ b/proxy/portal/logo_provider_test.go @@ -1,6 +1,9 @@ package portal_test import ( + "io" + "net/http" + "net/http/httptest" "testing" "time" @@ -13,9 +16,22 @@ import ( func TestLogoProvider(t *testing.T) { t.Parallel() + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/icon": + w.Header().Set("Content-Type", "image/vnd.microsoft.icon") + io.WriteString(w, "NOT ACTUALLY AN ICON") + case "/": + io.WriteString(w, ``) + default: + http.NotFound(w, r) + } + })) + t.Cleanup(srv.Close) + ctx := testutil.GetContext(t, time.Minute) p := portal.NewLogoProvider() - u, err := p.GetLogoURL(ctx, "", "https://www.wikipedia.org") + u, err := p.GetLogoURL(ctx, "", srv.URL) assert.NoError(t, err) - assert.Equal(t, "data:image/vnd.microsoft.icon;base64,AAABAAMAMDAQAAEABABoBgAANgAAACAgEAABAAQA6AIAAJ4GAAAQEBAAAQAEACgBAACGCQAAKAAAADAAAABgAAAAAQAEAAAAAAAABgAAAAAAAAAAAAAQAAAAAAAAAAEBAQAXFxcAMDAwAEdHRwBYWFgAZ2dnAHZ2dgCHh4cAlZWVAKmpqQC3t7cAx8fHANfX1wDo6OgA_v7-AAAAAAD____-7u7u7u7u7u7u7u7u7u7u7u_______-7u7u7u7u7u7u7u7u7u7u7u7u7u_____u7u7u7u7u7u7u7u7u7u7u7u7u7u7___7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v_-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u_-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u_-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u_u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7sa-7u7u7u1b7u7u7u7u7u7u7u7u7u7u7p9u7u7u7ugG7u7u7u7u7u7u7u7u7u7u7TAa7u7u7tQBzu7u7u7u7u7u7u7u7u7u6wAF7u7u7pAAju7u7u7u7u7u7u7u7u7u1AAAru7u7U__Le7u7u7u7u7u7u7u7u7uz_8RPe7u6gAB-e7u7u7u7u7u7u7u7u7ubw94Ce7u1QAIIu7u7u7u7u7u7u7u7u7tH_G-Mt7usAAtcL7u7u7u7u7u7u7u7u7n8ATun47uQACO0T7u7u7u7u7u7u7u7u7hDxnu4x3sAPLO5Qzu7u7u7u7u7u7u7u6P_z7u6wXk_wfu7ATu7u7u7u7u7u7u7u4QAY7u7kCQADzu7kDO7u7u7u7u7u7u7uoA8u7u7sAAAG7u7r9e7u7u7u7u7u7u7uIPB-7u7uUAAs7u7uMd7u7u7u7u7u7u7rEAHe7u7uQABu7u7un37u7u7u7u7u7u7kAAXu7u7sAPHe7u7u4S3u7u7u7u7u7u7BAA3u7u7k8AHO7u7u6Aju7u7u7u7u7u5g_07u7u7B8BBe7u7u7RLu7u7u7u7u7u0v_87u7u5QAGQa7u7u7nCe7u7u7u7u7ugAA-7u7uwQ8dsE7u7u7rBO7u7u7u7u7tP_--7u7uYAB-5Qnu7u7tQa7u7u7u7u7pH_Lu7u7sLwHe6xPe7u7ur27u7u7u7u7V__ru7u7mAAju7n-e7u7u0yvu7u7u7u6h8C3u7u6yAB3u7rEs7u7u6Pfu7u7u7u1AAE7u7u5g_27u7tQG3u7u6QHO7u7u7tbwAB3u7ukfAH7u7sIAju7u5wA97u7utiAAAAF76lAA_wWeyDAA84zqUAABfO7uMiNERDIm4iNERDIrkiNEQybiI0RDJO7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u_-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u_-7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u__7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v___u7u7u7u7u7u7u7u7u7u7u7u7u7u7____-7u7u7u7u7u7u7u7u7u7u7u7u7u_______-7u7u7u7u7u7u7u7u7u7u7u_____-AAAAAH8AAPAAAAAADwAA4AAAAAAHAADAAAAAAAMAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAwAAAAAADAADgAAAAAAcAAPAAAAAADwAA_gAAAAB_AAAoAAAAIAAAAEAAAAABAAQAAAAAAIACAAAAAAAAAAAAABAAAAAAAAAAAQEBABYWFgAnJycANTU1AEdHRwBZWVkAZWVlAHh4eACIiIgAmZmZAK6urgDMzMwA19fXAOnp6QD-_v4AAAAAAP__7u7u7u7u7u7u7u7u____7u7u7u7u7u7u7u7u7u7__u7u7u7u7u7u7u7u7u7u7_7u7u7u7u7u7u7u7u7u7u_u7u7u7u7u7u7u7u7u7u7u7u7u7u7X3u7u7I7u7u7u7u7u7u7uYF7u7uIK7u7u7u7u7u7u7QAM7u6vBO7u7u7u7u7u7ucABe7uMA_O7u7u7u7u7u7R8q_O6gCEbu7u7u7u7u7ukAnibuTx6g3u7u7u7u7u7hAe6gzP-O4Y7u7u7u7u7urwju4mXx7uge7u7u7u7u7jAd7uoACO7tCe7u7u7u7uoPfu7uEB3u7mPu7u7u7u7k8N7u7QBu7u6wru7u7u7uwAXu7ufwbu7u407u7u7u7lAM7u7RBQzu7ur87u7u7u0ATu7ucA0l7u7uFu7u7u7n_67u7RB-oL7u7nHe7u7u0fPu7ucA3uJO7u7Qju7u7o_67u7Q9u7q-u7u5R3u7u0Q_e7ub_vu7PLO7uX13u4w__Be4v_xnoH_-ekv__Xu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7-7u7u7u7u7u7u7u7u7u7v_u7u7u7u7u7u7u7u7u7u7__u7u7u7u7u7u7u7u7u7v___-7u7u7u7u7u7u7u7v__8AAAD8AAAAOAAAABgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA_AAAA8oAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAABAAAAAAAAAAAQEBABcXFwAnJycAOzs7AElJSQBpaWkAeXl5AIaGhgCVlZUApqamALOzswDMzMwA2dnZAObm5gD-_v4AAAAAAP_u7u7u7u7__u7u7u7u7u_u7uzu7t7u7u7u4Y7lTu7u7u6QTtA77u7u7iaoctXu7u7qDOQZ5d7u7uRO5R7rbu7uv77iLu5O7u5D7pGn7pju7QrtKOTe4-6z-OT40z2RTO7u7u7u7u7u7u7u7u7u7u7-7u7u7u7u7__u7u7u7u7_wAMAD4ABAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA-AAQAPwAMADw==", u) + assert.Equal(t, "data:image/vnd.microsoft.icon;base64,Tk9UIEFDVFVBTExZIEFOIElDT04=", u) }