package server import ( "net/http" "strings" "codeberg.org/codeberg/pages/html" "codeberg.org/codeberg/pages/server/cache" "codeberg.org/codeberg/pages/server/context" "codeberg.org/codeberg/pages/server/gitea" "codeberg.org/codeberg/pages/server/upstream" "github.com/rs/zerolog" ) // tryUpstream forwards the target request to the Gitea API, and shows an error page on failure. func tryUpstream(ctx *context.Context, giteaClient *gitea.Client, mainDomainSuffix, trimmedHost string, targetOptions *upstream.Options, targetOwner, targetRepo, targetBranch, targetPath string, canonicalDomainCache cache.SetGetKey, ) { // check if a canonical domain exists on a request on MainDomain if strings.HasSuffix(trimmedHost, mainDomainSuffix) { canonicalDomain, _ := upstream.CheckCanonicalDomain(giteaClient, targetOwner, targetRepo, targetBranch, "", string(mainDomainSuffix), canonicalDomainCache) if !strings.HasSuffix(strings.SplitN(canonicalDomain, "/", 2)[0], string(mainDomainSuffix)) { canonicalPath := ctx.Req.RequestURI if targetRepo != "pages" { path := strings.SplitN(canonicalPath, "/", 3) if len(path) >= 3 { canonicalPath = "/" + path[2] } } ctx.Redirect("https://"+canonicalDomain+canonicalPath, http.StatusTemporaryRedirect) return } } targetOptions.TargetOwner = targetOwner targetOptions.TargetRepo = targetRepo targetOptions.TargetBranch = targetBranch targetOptions.TargetPath = targetPath targetOptions.Host = string(trimmedHost) // Try to request the file from the Gitea API if !targetOptions.Upstream(ctx, giteaClient) { html.ReturnErrorPage(ctx, "", ctx.StatusCode) } } // tryBranch checks if a branch exists and populates the target variables. If canonicalLink is non-empty, // it will also disallow search indexing and add a Link header to the canonical URL. func tryBranch(log zerolog.Logger, ctx *context.Context, giteaClient *gitea.Client, repoOwner, repoName, branch, path string, canonicalLink bool, ) (*gitea.BranchTimestamp, bool) { if repoName == "" { log.Debug().Msg("tryBranch: repo is empty") return nil, false } // Replace "~" to "/" so we can access branch that contains slash character // Branch name cannot contain "~" so doing this is okay branch = strings.ReplaceAll(branch, "~", "/") // Check if the branch exists, otherwise treat it as a file path branchTimestampResult := upstream.GetBranchTimestamp(giteaClient, repoOwner, repoName, branch) if branchTimestampResult == nil { log.Debug().Msg("tryBranch: branch doesn't exist") return nil, false } if canonicalLink { // Hide from search machines & add canonical link ctx.RespWriter.Header().Set("X-Robots-Tag", "noarchive, noindex") ctx.RespWriter.Header().Set("Link", giteaClient.ContentWebLink(repoOwner, repoName, branchTimestampResult.Branch, path)+ "; rel=\"canonical\"") } log.Debug().Msg("tryBranch: true") return branchTimestampResult, true }