fix: a loop through the site's absolute URL lists each address once
The loop and chain path of a redirect notice appended the final target when it was an absolute URL of the site itself, so a loop read "/a → /b → /a → https://example.test/a". The site URL now counts as internal, as it does when the chain is followed.
This commit is contained in:
@@ -170,7 +170,7 @@ func (s *Service) Issues(ctx context.Context) ([]Issue, error) {
|
||||
continue
|
||||
}
|
||||
out = append(out, Issue{Kind: IssueRedirectChain, URL: r.Source, Tool: toolUpdateRedirect, Details: map[string]any{
|
||||
"redirect_id": r.ID, "hops": len(ch.Hops), "final": displayURL(site, ch.Final), "path": displayPath(r, ch),
|
||||
"redirect_id": r.ID, "hops": len(ch.Hops), "final": displayURL(site, ch.Final), "path": displayPath(site, r, ch),
|
||||
}})
|
||||
}
|
||||
|
||||
|
||||
@@ -203,11 +203,11 @@ func checkRedirectRules(site string, rules []models.Redirect, r models.Redirect)
|
||||
return check, err
|
||||
}
|
||||
if ch.Loop {
|
||||
check.Loop, check.Path = true, displayPath(r, ch)
|
||||
check.Loop, check.Path = true, displayPath(site, r, ch)
|
||||
return check, nil
|
||||
}
|
||||
if len(ch.Hops) > 1 && ch.Hops[0].Rule.ID == r.ID {
|
||||
check.Chain, check.Path, check.Hops = true, displayPath(r, ch), len(ch.Hops)
|
||||
check.Chain, check.Path, check.Hops = true, displayPath(site, r, ch), len(ch.Hops)
|
||||
check.Source, check.Final = r.Source, displayURL(site, ch.Final)
|
||||
return check, nil
|
||||
}
|
||||
@@ -233,15 +233,17 @@ func checkRedirectRules(site string, rules []models.Redirect, r models.Redirect)
|
||||
return check, err
|
||||
}
|
||||
check.Chain, check.Hops = true, len(ch.Hops)+1
|
||||
check.Path = append([]string{other.Source}, displayPath(r, ch)...)
|
||||
check.Path = append([]string{other.Source}, displayPath(site, r, ch)...)
|
||||
check.Source, check.Final = other.Source, displayURL(site, ch.Final)
|
||||
return check, nil
|
||||
}
|
||||
return check, nil
|
||||
}
|
||||
|
||||
// displayPath lists a chain's URLs for a notice, the source of r first.
|
||||
func displayPath(r models.Redirect, ch Chain) []string {
|
||||
// displayPath lists a chain's URLs for a notice, the source of r first. A
|
||||
// final target outside the site ends the list; one on the site (a path or
|
||||
// the site's absolute URL) is already its last visited path.
|
||||
func displayPath(site string, r models.Redirect, ch Chain) []string {
|
||||
out := make([]string, 0, len(ch.Visited))
|
||||
for i, v := range ch.Visited {
|
||||
if i == 0 && r.Match != models.RedirectExact && len(ch.Hops) > 0 && ch.Hops[0].Rule.ID == r.ID {
|
||||
@@ -251,7 +253,7 @@ func displayPath(r models.Redirect, ch Chain) []string {
|
||||
}
|
||||
if len(ch.Hops) > 0 && ch.Final != "" {
|
||||
if last := out[len(out)-1]; last != ch.Final {
|
||||
if _, _, internal := internalTarget("", ch.Final); !internal {
|
||||
if _, _, internal := internalTarget(site, ch.Final); !internal {
|
||||
out = append(out, ch.Final)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user