diff --git a/server/upstream/upstream.go b/server/upstream/upstream.go index 33c80e9..d7eedae 100644 --- a/server/upstream/upstream.go +++ b/server/upstream/upstream.go @@ -12,6 +12,7 @@ import ( "github.com/rs/zerolog/log" "github.com/valyala/fasthttp" + "github.com/valyala/fastjson" "codeberg.org/codeberg/pages/html" "codeberg.org/codeberg/pages/server/cache" @@ -80,6 +81,26 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaRoot, giteaAPIToken st } } log.Debug().Msg("preparations") + + // We try to find out if the file is a symlink + uriContent := path.Join(o.TargetOwner, o.TargetRepo, "contents", o.TargetPath) + "?ref=" + o.TargetBranch + var reqContent *fasthttp.Request + var resContent *fasthttp.Response + reqContent = fasthttp.AcquireRequest() + reqContent.SetRequestURI(path.Join(giteaRoot, giteaAPIRepos, uriContent)) + reqContent.Header.Set(fasthttp.HeaderAuthorization, giteaAPIToken) + resContent = fasthttp.AcquireResponse() + resContent.SetBodyStream(&strings.Reader{}, -1) + errContent := getFastHTTPClient(10*time.Second).Do(reqContent, resContent) + if errContent == nil { + contentBody := resContent.Body() + if fastjson.GetString(contentBody, "type") == "symlink" { + symlinkTarget := fastjson.GetString(contentBody, "target") + log.Debug().Msg(o.TargetPath + " is a symlink to " + symlinkTarget) + ctx.Redirect(symlinkTarget, fasthttp.StatusTemporaryRedirect) + return true + } + } // Make a GET request to the upstream URL uri := path.Join(o.TargetOwner, o.TargetRepo, "raw", o.TargetBranch, o.TargetPath)