mirror of
https://codeberg.org/git-pages/git-pages.git
synced 2026-10-22 07:22:33 +00:00
Check validity of URL rewrite rules for non-index projects.
In commit 600c8a7848, we have introduced
an unintentionally breaking change to how redirects are handled, thus
breaking every single-page application deployed to a non-index project.
This cannot be easily fixed due to Codeberg Pages already having a mix
of broken and fixed redirects in manifests without any way to tell them
apart, but we can at least emit a diagnostic for redirects that are
statically known to be broken at deploy time.
See also #273.
This commit is contained in:
+4
-2
@@ -338,9 +338,11 @@ func CompressFiles(ctx context.Context, manifest *Manifest) {
|
||||
// Apply post-processing steps to the manifest.
|
||||
// At the moment, there isn't a good way to report errors except to log them on the terminal.
|
||||
// (Perhaps in the future they could be exposed at `.git-pages/status.txt`?)
|
||||
func PrepareManifest(ctx context.Context, manifest *Manifest) error {
|
||||
func PrepareManifest(ctx context.Context, webRoot string, manifest *Manifest) error {
|
||||
_, project, _ := strings.Cut(webRoot, "/")
|
||||
|
||||
// Parse Netlify-style `_redirects`.
|
||||
if err := ProcessRedirectsFile(ctx, manifest); err != nil {
|
||||
if err := ProcessRedirectsFile(ctx, project, manifest); err != nil {
|
||||
logc.Printf(ctx, "redirects err: %s\n", err)
|
||||
} else if len(manifest.Redirects) > 0 {
|
||||
logc.Printf(ctx, "redirects ok: %d rules\n", len(manifest.Redirects))
|
||||
|
||||
+12
-3
@@ -43,7 +43,7 @@ func Is3xxHTTPStatus(status int) bool {
|
||||
return status >= 300 && status <= 399
|
||||
}
|
||||
|
||||
func validateRedirectRule(rule *redirects.Rule) error {
|
||||
func validateRedirectRule(project string, rule *redirects.Rule) error {
|
||||
if len(rule.Params) > 0 {
|
||||
return fmt.Errorf("rules with parameters are not supported")
|
||||
}
|
||||
@@ -76,11 +76,20 @@ func validateRedirectRule(rule *redirects.Rule) error {
|
||||
return fmt.Errorf("'to' URL may only include a hostname for 3xx status rules")
|
||||
}
|
||||
}
|
||||
// After v0.9.1, we've changed the redirect handling so that the 'to' URL for a rewrite rule
|
||||
// must be a valid URL pointing to this site, rather than a valid path within the manifest
|
||||
// (which was the old, incorrect interpretation). This broke every SPA on git-pages that was
|
||||
// deployed to a non-index project. Unfortunately, we can't do much more than diagnosing
|
||||
// the problematic pattern at deploy time.
|
||||
if rule.Status == http.StatusOK && project != ".index" && toURL.Host == "" &&
|
||||
!strings.HasPrefix(toURL.Path, fmt.Sprintf("/%s/", project)) {
|
||||
return fmt.Errorf("'to' URL must start with '/%s/' for a 200 status rule", project)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parses redirects file and injects rules into the manifest.
|
||||
func ProcessRedirectsFile(ctx context.Context, manifest *Manifest) error {
|
||||
func ProcessRedirectsFile(ctx context.Context, project string, manifest *Manifest) error {
|
||||
redirectsEntry := manifest.Contents[RedirectsFileName]
|
||||
delete(manifest.Contents, RedirectsFileName)
|
||||
if redirectsEntry == nil {
|
||||
@@ -103,7 +112,7 @@ func ProcessRedirectsFile(ctx context.Context, manifest *Manifest) error {
|
||||
}
|
||||
|
||||
for index, rule := range rules {
|
||||
if err := validateRedirectRule(&rule); err != nil {
|
||||
if err := validateRedirectRule(project, &rule); err != nil {
|
||||
ruleString := redirects.Must(redirects.UnparseString([]redirects.Rule{rule}))
|
||||
AddProblem(manifest, RedirectsFileName,
|
||||
"rule #%d %q: %s", index+1, strings.TrimSpace(ruleString), err)
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ func Update(
|
||||
outcome = UpdateDeleted
|
||||
}
|
||||
}
|
||||
} else if err = PrepareManifest(ctx, newManifest); err == nil {
|
||||
} else if err = PrepareManifest(ctx, webRoot, newManifest); err == nil {
|
||||
storedManifest, err = StoreManifest(ctx, webRoot, newManifest, opts)
|
||||
if err == nil {
|
||||
domain, _, _ := strings.Cut(webRoot, "/")
|
||||
|
||||
Reference in New Issue
Block a user