package classes import ( "context" "net/url" "strings" "git.golem15.com/golem15/summercms/modules/pact" ) // StrictMatch is the record behind a path and whether the path is its // address (D-20c). Key is "" when no published record answers the path. type StrictMatch struct { Key string Match *pact.ContentMatchResult Record *pact.ContentRecord // Canonical is the record's own path in the matched locale, in the // site's address form; "" when the descriptor answers none. Canonical string // Mismatch is true when the path names the record but is not its // address: a wrong category or parent, a locale prefix with another // locale's slug, a moved record. It then 301s to Canonical. Mismatch bool } // Strict finds the published record behind path through the signpost // patterns (MatchPath) and checks every segment against the record's own // address (D-20c): a path that names a record without being its address // is a mismatch, so a wrong URL never answers ok. The comparison uses the // site's address form (opts), so a strict 301 and normalisation never // send a visitor back and forth. func (r *Resolver) Strict(ctx context.Context, path string, opts NormalizeOptions) (StrictMatch, error) { var out StrictMatch reg := r.Service.Registry() if reg == nil { return out, nil } unprefixed := r.Service.UnprefixedLocale() // Content patterns carry no trailing slash; the site's trailing-slash // rule is applied to the record's address below. key, match, err := reg.MatchPath(ctx, trimSlash(path), unprefixed) if err != nil || match == nil { return out, err } rec, err := reg.Describe(ctx, key, match.ID, unprefixed) if err != nil || rec == nil || !rec.Published { return out, err } out.Key, out.Match, out.Record = key, match, rec described := "" for _, l := range rec.Locales { if l.Locale == match.Locale { described = strings.TrimSpace(l.URL) } } if described == "" { out.Mismatch = !match.Exact return out, nil } du, err := url.Parse(described) if err != nil { return out, nil } canonical, _ := Normalize(&url.URL{Path: du.Path}, opts) out.Canonical = canonical.Path out.Mismatch = !match.Exact || canonical.Path != path return out, nil }