diff --git a/server/handler.go b/server/handler.go index 1031716..1aaf476 100644 --- a/server/handler.go +++ b/server/handler.go @@ -144,19 +144,19 @@ func Handler(mainDomainSuffix, rawDomain []byte, log.Debug().Msg("missing branch") html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) return - } else { - log.Debug().Msg("raw domain preparations, now trying with default branch") - tryBranch(targetRepo, "", pathElements[2:], - giteaRoot+"/"+targetOwner+"/"+targetRepo+"/src/branch/%b/%p", - ) - log.Debug().Msg("tryBranch, now trying upstream") - tryUpstream(ctx, mainDomainSuffix, trimmedHost, - targetOptions, targetOwner, targetRepo, targetBranch, targetPath, - giteaRoot, giteaAPIToken, - canonicalDomainCache, branchTimestampCache, fileResponseCache) - return } + log.Debug().Msg("raw domain preparations, now trying with default branch") + tryBranch(targetRepo, "", pathElements[2:], + giteaRoot+"/"+targetOwner+"/"+targetRepo+"/src/branch/%b/%p", + ) + log.Debug().Msg("tryBranch, now trying upstream") + tryUpstream(ctx, mainDomainSuffix, trimmedHost, + targetOptions, targetOwner, targetRepo, targetBranch, targetPath, + giteaRoot, giteaAPIToken, + canonicalDomainCache, branchTimestampCache, fileResponseCache) + return + } else if bytes.HasSuffix(trimmedHost, mainDomainSuffix) { // Serve pages from subdomains of MainDomainSuffix log.Debug().Msg("main domain suffix") @@ -167,7 +167,7 @@ func Handler(mainDomainSuffix, rawDomain []byte, targetPath = strings.Trim(strings.Join(pathElements[1:], "/"), "/") if targetOwner == "www" { - // www.codeberg.page redirects to codeberg.page + // www.codeberg.page redirects to codeberg.page // TODO: rm hardcoded - use cname? ctx.Redirect("https://"+string(mainDomainSuffix[1:])+string(ctx.Path()), fasthttp.StatusPermanentRedirect) return } @@ -271,10 +271,10 @@ func Handler(mainDomainSuffix, rawDomain []byte, if targetOwner != "" { ctx.Redirect("https://"+canonicalDomain+string(ctx.RequestURI()), fasthttp.StatusTemporaryRedirect) return - } else { - html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) - return } + + html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) + return } log.Debug().Msg("tryBranch, now trying upstream") @@ -283,10 +283,10 @@ func Handler(mainDomainSuffix, rawDomain []byte, giteaRoot, giteaAPIToken, canonicalDomainCache, branchTimestampCache, fileResponseCache) return - } else { - html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) - return } + + html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) + return } } } diff --git a/server/try.go b/server/try.go index 0636ffc..7223dfa 100644 --- a/server/try.go +++ b/server/try.go @@ -20,6 +20,7 @@ func tryUpstream(ctx *fasthttp.RequestCtx, giteaRoot, giteaAPIToken string, canonicalDomainCache, branchTimestampCache, fileResponseCache cache.SetGetKey) { + // check if a canonical domain exists on a request on MainDomain if bytes.HasSuffix(trimmedHost, mainDomainSuffix) { canonicalDomain, _ := upstream.CheckCanonicalDomain(targetOwner, targetRepo, targetBranch, "", string(mainDomainSuffix), giteaRoot, giteaAPIToken, canonicalDomainCache) @@ -33,8 +34,13 @@ func tryUpstream(ctx *fasthttp.RequestCtx, } } + targetOptions.TargetOwner = targetOwner + targetOptions.TargetRepo = targetRepo + targetOptions.TargetBranch = targetBranch + targetOptions.TargetPath = targetPath + // Try to request the file from the Gitea API - if !targetOptions.Upstream(ctx, targetOwner, targetRepo, targetBranch, targetPath, giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { + if !targetOptions.Upstream(ctx, giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { html.ReturnErrorPage(ctx, ctx.Response.StatusCode()) } } diff --git a/server/upstream/upstream.go b/server/upstream/upstream.go index 2338ef2..925183a 100644 --- a/server/upstream/upstream.go +++ b/server/upstream/upstream.go @@ -24,7 +24,12 @@ var upstreamIndexPages = []string{ // Options provides various options for the upstream request. type Options struct { - DefaultMimeType string + TargetOwner, + TargetRepo, + TargetBranch, + TargetPath, + + DefaultMimeType string ForbiddenMimeTypes map[string]struct{} TryIndexPages bool BranchTimestamp time.Time @@ -41,26 +46,26 @@ var client = fasthttp.Client{ } // Upstream requests a file from the Gitea API at GiteaRoot and writes it to the request context. -func (o *Options) Upstream(ctx *fasthttp.RequestCtx, targetOwner, targetRepo, targetBranch, targetPath, giteaRoot, giteaAPIToken string, branchTimestampCache, fileResponseCache cache.SetGetKey) (final bool) { - log := log.With().Strs("upstream", []string{targetOwner, targetRepo, targetBranch, targetPath}).Logger() +func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaRoot, giteaAPIToken string, branchTimestampCache, fileResponseCache cache.SetGetKey) (final bool) { + log := log.With().Strs("upstream", []string{o.TargetOwner, o.TargetRepo, o.TargetBranch, o.TargetPath}).Logger() if o.ForbiddenMimeTypes == nil { o.ForbiddenMimeTypes = map[string]struct{}{} } // Check if the branch exists and when it was modified - if o.BranchTimestamp == (time.Time{}) { - branch := GetBranchTimestamp(targetOwner, targetRepo, targetBranch, giteaRoot, giteaAPIToken, branchTimestampCache) + if o.BranchTimestamp.IsZero() { + branch := GetBranchTimestamp(o.TargetOwner, o.TargetRepo, o.TargetBranch, giteaRoot, giteaAPIToken, branchTimestampCache) if branch == nil { html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) return true } - targetBranch = branch.Branch + o.TargetBranch = branch.Branch o.BranchTimestamp = branch.Timestamp } - if targetOwner == "" || targetRepo == "" || targetBranch == "" { + if o.TargetOwner == "" || o.TargetRepo == "" || o.TargetBranch == "" { html.ReturnErrorPage(ctx, fasthttp.StatusBadRequest) return true } @@ -75,7 +80,7 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, targetOwner, targetRepo, ta log.Debug().Msg("preparations") // Make a GET request to the upstream URL - uri := targetOwner + "/" + targetRepo + "/raw/" + targetBranch + "/" + targetPath + uri := o.TargetOwner + "/" + o.TargetRepo + "/raw/" + o.TargetBranch + "/" + o.TargetPath var req *fasthttp.Request var res *fasthttp.Response var cachedResponse fileResponse @@ -99,7 +104,8 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, targetOwner, targetRepo, ta optionsForIndexPages.TryIndexPages = false optionsForIndexPages.appendTrailingSlash = true for _, indexPage := range upstreamIndexPages { - if optionsForIndexPages.Upstream(ctx, targetOwner, targetRepo, targetBranch, strings.TrimSuffix(targetPath, "/")+"/"+indexPage, giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { + optionsForIndexPages.TargetPath = strings.TrimSuffix(o.TargetPath, "/") + "/" + indexPage + if optionsForIndexPages.Upstream(ctx, giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { _ = fileResponseCache.Set(uri+"?timestamp="+strconv.FormatInt(o.BranchTimestamp.Unix(), 10), fileResponse{ exists: false, }, fileCacheTimeout) @@ -109,7 +115,8 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, targetOwner, targetRepo, ta // compatibility fix for GitHub Pages (/example → /example.html) optionsForIndexPages.appendTrailingSlash = false optionsForIndexPages.redirectIfExists = string(ctx.Request.URI().Path()) + ".html" - if optionsForIndexPages.Upstream(ctx, targetOwner, targetRepo, targetBranch, targetPath+".html", giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { + optionsForIndexPages.TargetPath = o.TargetPath + ".html" + if optionsForIndexPages.Upstream(ctx, giteaRoot, giteaAPIToken, branchTimestampCache, fileResponseCache) { _ = fileResponseCache.Set(uri+"?timestamp="+strconv.FormatInt(o.BranchTimestamp.Unix(), 10), fileResponse{ exists: false, }, fileCacheTimeout) @@ -148,7 +155,7 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, targetOwner, targetRepo, ta log.Debug().Msg("error handling") // Set the MIME type - mimeType := mime.TypeByExtension(path.Ext(targetPath)) + mimeType := mime.TypeByExtension(path.Ext(o.TargetPath)) mimeTypeSplit := strings.SplitN(mimeType, ";", 2) if _, ok := o.ForbiddenMimeTypes[mimeTypeSplit[0]]; ok || mimeType == "" { if o.DefaultMimeType != "" { diff --git a/server/utils/utils_test.go b/server/utils/utils_test.go new file mode 100644 index 0000000..3dc0632 --- /dev/null +++ b/server/utils/utils_test.go @@ -0,0 +1,13 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTrimHostPort(t *testing.T) { + assert.EqualValues(t, "aa", TrimHostPort([]byte("aa"))) + assert.EqualValues(t, "", TrimHostPort([]byte(":"))) + assert.EqualValues(t, "example.com", TrimHostPort([]byte("example.com:80"))) +}