@@ -17,6 +17,7 @@ import (
1717 "fmt"
1818 "io"
1919 "net/http"
20+ "net/url"
2021 "regexp"
2122 "strings"
2223 "time"
@@ -117,7 +118,9 @@ func Favicon(targetURL string, timeout time.Duration, logdir string) (*FaviconRe
117118// homepage html. it returns the url it pulled the bytes from so the report shows
118119// exactly which icon was hashed.
119120func fetchFavicon (client * http.Client , base string ) (string , []byte , error ) {
120- iconURL := base + "/favicon.ico"
121+ // the well-known icon always lives at the origin root, so resolve it there
122+ // rather than appending to a target that may carry a path.
123+ iconURL := resolveFaviconURL (base , "/favicon.ico" )
121124 if data , err := getFaviconBytes (client , iconURL ); err == nil {
122125 return iconURL , data , nil
123126 }
@@ -191,23 +194,20 @@ func declaredFaviconHref(client *http.Client, base string) (string, error) {
191194}
192195
193196// resolveFaviconURL turns a possibly-relative href into an absolute url against
194- // the target base. an absolute href is returned as-is.
197+ // the target base, resolving it the way a browser would: a root-relative href
198+ // anchors at the origin (not the target's path), a scheme-relative href inherits
199+ // the base scheme, and an absolute href is returned as-is. a base or href that
200+ // won't parse falls back to the raw href rather than fetching a mangled url.
195201func resolveFaviconURL (base , href string ) string {
196- if strings .HasPrefix (href , "http://" ) || strings .HasPrefix (href , "https://" ) {
202+ baseURL , err := url .Parse (base )
203+ if err != nil {
197204 return href
198205 }
199- if strings .HasPrefix (href , "//" ) {
200- // scheme-relative; inherit the base scheme.
201- scheme := "https:"
202- if strings .HasPrefix (base , "http://" ) {
203- scheme = "http:"
204- }
205- return scheme + href
206- }
207- if strings .HasPrefix (href , "/" ) {
208- return base + href
206+ ref , err := url .Parse (href )
207+ if err != nil {
208+ return href
209209 }
210- return base + "/" + href
210+ return baseURL . ResolveReference ( ref ). String ()
211211}
212212
213213// ResultType identifies favicon findings for the result registry.
0 commit comments