more caching in-client

This commit is contained in:
6543 2022-07-27 15:39:46 +02:00
parent b2b22872a2
commit a8afb372dd
No known key found for this signature in database
GPG key ID: C99B82E40B027BAE
11 changed files with 95 additions and 80 deletions

View file

@ -76,13 +76,10 @@ func Serve(ctx *cli.Context) error {
canonicalDomainCache := cache.NewKeyValueCache() canonicalDomainCache := cache.NewKeyValueCache()
// dnsLookupCache stores DNS lookups for custom domains // dnsLookupCache stores DNS lookups for custom domains
dnsLookupCache := cache.NewKeyValueCache() dnsLookupCache := cache.NewKeyValueCache()
// branchTimestampCache stores branch timestamps for faster cache checking // clientResponseCache stores responses from the Gitea server
branchTimestampCache := cache.NewKeyValueCache() clientResponseCache := cache.NewKeyValueCache()
// fileResponseCache stores responses from the Gitea server
// TODO: make this an MRU cache with a size limit
fileResponseCache := cache.NewKeyValueCache()
giteaClient, err := gitea.NewClient(giteaRoot, giteaAPIToken, fileResponseCache, ctx.Bool("enable-symlink-support"), ctx.Bool("enable-lfs-support")) giteaClient, err := gitea.NewClient(giteaRoot, giteaAPIToken, clientResponseCache, ctx.Bool("enable-symlink-support"), ctx.Bool("enable-lfs-support"))
if err != nil { if err != nil {
return fmt.Errorf("could not create new gitea client: %v", err) return fmt.Errorf("could not create new gitea client: %v", err)
} }
@ -92,7 +89,7 @@ func Serve(ctx *cli.Context) error {
giteaClient, giteaClient,
giteaRoot, rawInfoPage, giteaRoot, rawInfoPage,
BlacklistedPaths, allowedCorsDomains, BlacklistedPaths, allowedCorsDomains,
dnsLookupCache, canonicalDomainCache, branchTimestampCache, fileResponseCache) dnsLookupCache, canonicalDomainCache)
fastServer := server.SetupServer(handler) fastServer := server.SetupServer(handler)
httpServer := server.SetupHTTPACMEChallengeServer(challengeCache) httpServer := server.SetupHTTPACMEChallengeServer(challengeCache)

View file

@ -1,5 +1,7 @@
package gitea package gitea
import "time"
type FileResponse struct { type FileResponse struct {
Exists bool Exists bool
ETag []byte ETag []byte
@ -10,3 +12,18 @@ type FileResponse struct {
func (f FileResponse) IsEmpty() bool { func (f FileResponse) IsEmpty() bool {
return len(f.Body) != 0 return len(f.Body) != 0
} }
type BranchTimestamp struct {
Branch string
Timestamp time.Time
}
var (
// defaultBranchCacheTimeout specifies the timeout for the default branch cache. It can be quite long.
defaultBranchCacheTimeout = 15 * time.Minute
// branchExistenceCacheTimeout specifies the timeout for the branch timestamp & existence cache. It should be shorter
// than fileCacheTimeout, as that gets invalidated if the branch timestamp has changed. That way, repo changes will be
// picked up faster, while still allowing the content to be cached longer if nothing changes.
branchExistenceCacheTimeout = 5 * time.Minute
)

View file

@ -5,3 +5,8 @@ import (
) )
var ErrorNotFound = errors.New("not found") var ErrorNotFound = errors.New("not found")
const (
branchTimestampCacheKeyPrefix = "branchTime"
defaultBranchCacheKeyPrefix = "defaultBranch"
)

View file

@ -21,28 +21,28 @@ const (
) )
type Client struct { type Client struct {
giteaRoot string giteaRoot string
giteaAPIToken string giteaAPIToken string
infoTimeout time.Duration infoTimeout time.Duration
contentTimeout time.Duration contentTimeout time.Duration
fastClient *fasthttp.Client fastClient *fasthttp.Client
fileResponseCache cache.SetGetKey responseCache cache.SetGetKey
followSymlinks bool followSymlinks bool
supportLFS bool supportLFS bool
} }
func NewClient(giteaRoot, giteaAPIToken string, fileResponseCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) { func NewClient(giteaRoot, giteaAPIToken string, respCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) {
rootURL, err := url.Parse(giteaRoot) rootURL, err := url.Parse(giteaRoot)
giteaRoot = strings.Trim(rootURL.String(), "/") giteaRoot = strings.Trim(rootURL.String(), "/")
return &Client{ return &Client{
giteaRoot: giteaRoot, giteaRoot: giteaRoot,
giteaAPIToken: giteaAPIToken, giteaAPIToken: giteaAPIToken,
infoTimeout: 5 * time.Second, infoTimeout: 5 * time.Second,
contentTimeout: 10 * time.Second, contentTimeout: 10 * time.Second,
fastClient: getFastHTTPClient(), fastClient: getFastHTTPClient(),
fileResponseCache: fileResponseCache, responseCache: respCache,
followSymlinks: followSymlinks, followSymlinks: followSymlinks,
supportLFS: supportLFS, supportLFS: supportLFS,

View file

@ -16,14 +16,14 @@ import (
) )
type Client struct { type Client struct {
sdkClient *gitea.Client sdkClient *gitea.Client
fileResponseCache cache.SetGetKey responseCache cache.SetGetKey
followSymlinks bool followSymlinks bool
supportLFS bool supportLFS bool
} }
func NewClient(giteaRoot, giteaAPIToken string, fileResponseCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) { func NewClient(giteaRoot, giteaAPIToken string, respCache cache.SetGetKey, followSymlinks, supportLFS bool) (*Client, error) {
rootURL, err := url.Parse(giteaRoot) rootURL, err := url.Parse(giteaRoot)
giteaRoot = strings.Trim(rootURL.String(), "/") giteaRoot = strings.Trim(rootURL.String(), "/")
@ -31,8 +31,8 @@ func NewClient(giteaRoot, giteaAPIToken string, fileResponseCache cache.SetGetKe
sdk, err := gitea.NewClient(giteaRoot, gitea.SetHTTPClient(&stdClient), gitea.SetToken(giteaAPIToken)) sdk, err := gitea.NewClient(giteaRoot, gitea.SetHTTPClient(&stdClient), gitea.SetToken(giteaAPIToken))
return &Client{ return &Client{
sdkClient: sdk, sdkClient: sdk,
fileResponseCache: fileResponseCache, responseCache: respCache,
}, err }, err
} }
@ -68,18 +68,40 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
} }
} }
func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchName string) (time.Time, error) { func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchName string) (*BranchTimestamp, error) {
cacheKey := fmt.Sprintf("%s/%s/%s/%s", branchTimestampCacheKeyPrefix, repoOwner, repoName, branchName)
if stamp, ok := client.responseCache.Get(cacheKey); ok && stamp != nil {
return stamp.(*BranchTimestamp), nil
}
branch, resp, err := client.sdkClient.GetRepoBranch(repoOwner, repoName, branchName) branch, resp, err := client.sdkClient.GetRepoBranch(repoOwner, repoName, branchName)
if err != nil { if err != nil {
return time.Time{}, err if resp != nil && resp.StatusCode == http.StatusNotFound {
return &BranchTimestamp{}, ErrorNotFound
}
return &BranchTimestamp{}, err
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return time.Time{}, fmt.Errorf("unexpected status code '%d'", resp.StatusCode) return &BranchTimestamp{}, fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
} }
return branch.Commit.Timestamp, nil
stamp := &BranchTimestamp{
Branch: branch.Name,
Timestamp: branch.Commit.Timestamp,
}
client.responseCache.Set(cacheKey, stamp, branchExistenceCacheTimeout)
return stamp, nil
} }
func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (string, error) { func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (string, error) {
cacheKey := fmt.Sprintf("%s/%s/%s", defaultBranchCacheKeyPrefix, repoOwner, repoName)
if branch, ok := client.responseCache.Get(cacheKey); ok && branch != nil {
return branch.(string), nil
}
repo, resp, err := client.sdkClient.GetRepo(repoOwner, repoName) repo, resp, err := client.sdkClient.GetRepo(repoOwner, repoName)
if err != nil { if err != nil {
return "", err return "", err
@ -87,5 +109,8 @@ func (client *Client) GiteaGetRepoDefaultBranch(repoOwner, repoName string) (str
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code '%d'", resp.StatusCode) return "", fmt.Errorf("unexpected status code '%d'", resp.StatusCode)
} }
return repo.DefaultBranch, nil
branch := repo.DefaultBranch
client.responseCache.Set(cacheKey, branch, defaultBranchCacheTimeout)
return branch, nil
} }

View file

@ -24,7 +24,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
giteaClient *gitea.Client, giteaClient *gitea.Client,
giteaRoot, rawInfoPage string, giteaRoot, rawInfoPage string,
blacklistedPaths, allowedCorsDomains [][]byte, blacklistedPaths, allowedCorsDomains [][]byte,
dnsLookupCache, canonicalDomainCache, branchTimestampCache, fileResponseCache cache.SetGetKey, dnsLookupCache, canonicalDomainCache cache.SetGetKey,
) func(ctx *fasthttp.RequestCtx) { ) func(ctx *fasthttp.RequestCtx) {
return func(ctx *fasthttp.RequestCtx) { return func(ctx *fasthttp.RequestCtx) {
log := log.With().Str("Handler", string(ctx.Request.Header.RequestURI())).Logger() log := log.With().Str("Handler", string(ctx.Request.Header.RequestURI())).Logger()
@ -96,7 +96,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
branch = strings.ReplaceAll(branch, "~", "/") branch = strings.ReplaceAll(branch, "~", "/")
// Check if the branch exists, otherwise treat it as a file path // Check if the branch exists, otherwise treat it as a file path
branchTimestampResult := upstream.GetBranchTimestamp(giteaClient, targetOwner, repo, branch, branchTimestampCache) branchTimestampResult := upstream.GetBranchTimestamp(giteaClient, targetOwner, repo, branch)
if branchTimestampResult == nil { if branchTimestampResult == nil {
log.Debug().Msg("tryBranch: branch doesn't exist") log.Debug().Msg("tryBranch: branch doesn't exist")
return false return false
@ -153,7 +153,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 1") log.Debug().Msg("tryBranch, now trying upstream 1")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
return return
} }
log.Debug().Msg("missing branch") log.Debug().Msg("missing branch")
@ -169,7 +169,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 2") log.Debug().Msg("tryBranch, now trying upstream 2")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
return return
} else if bytes.HasSuffix(trimmedHost, mainDomainSuffix) { } else if bytes.HasSuffix(trimmedHost, mainDomainSuffix) {
@ -204,7 +204,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 3") log.Debug().Msg("tryBranch, now trying upstream 3")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
} else { } else {
html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency)
} }
@ -220,7 +220,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 4") log.Debug().Msg("tryBranch, now trying upstream 4")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
} else { } else {
html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency)
} }
@ -236,7 +236,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 5") log.Debug().Msg("tryBranch, now trying upstream 5")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
return return
} }
@ -248,7 +248,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 6") log.Debug().Msg("tryBranch, now trying upstream 6")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
return return
} }
@ -296,7 +296,7 @@ func Handler(mainDomainSuffix, rawDomain []byte,
log.Debug().Msg("tryBranch, now trying upstream 7") log.Debug().Msg("tryBranch, now trying upstream 7")
tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost, tryUpstream(ctx, giteaClient, mainDomainSuffix, trimmedHost,
targetOptions, targetOwner, targetRepo, targetBranch, targetPath, targetOptions, targetOwner, targetRepo, targetBranch, targetPath,
canonicalDomainCache, branchTimestampCache, fileResponseCache) canonicalDomainCache)
return return
} }

View file

@ -24,8 +24,6 @@ func TestHandlerPerformance(t *testing.T) {
[][]byte{[]byte("raw.codeberg.org"), []byte("fonts.codeberg.org"), []byte("design.codeberg.org")}, [][]byte{[]byte("raw.codeberg.org"), []byte("fonts.codeberg.org"), []byte("design.codeberg.org")},
cache.NewKeyValueCache(), cache.NewKeyValueCache(),
cache.NewKeyValueCache(), cache.NewKeyValueCache(),
cache.NewKeyValueCache(),
cache.NewKeyValueCache(),
) )
testCase := func(uri string, status int) { testCase := func(uri string, status int) {

View file

@ -21,7 +21,7 @@ func tryUpstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
targetOptions *upstream.Options, targetOptions *upstream.Options,
targetOwner, targetRepo, targetBranch, targetPath string, targetOwner, targetRepo, targetBranch, targetPath string,
canonicalDomainCache, branchTimestampCache, fileResponseCache cache.SetGetKey, canonicalDomainCache cache.SetGetKey,
) { ) {
// check if a canonical domain exists on a request on MainDomain // check if a canonical domain exists on a request on MainDomain
if bytes.HasSuffix(trimmedHost, mainDomainSuffix) { if bytes.HasSuffix(trimmedHost, mainDomainSuffix) {
@ -45,7 +45,7 @@ func tryUpstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
targetOptions.TargetPath = targetPath targetOptions.TargetPath = targetPath
// Try to request the file from the Gitea API // Try to request the file from the Gitea API
if !targetOptions.Upstream(ctx, giteaClient, branchTimestampCache, fileResponseCache) { if !targetOptions.Upstream(ctx, giteaClient, branchTimestampCache) {
html.ReturnErrorPage(ctx, ctx.Response.StatusCode()) html.ReturnErrorPage(ctx, ctx.Response.StatusCode())
} }
} }

View file

@ -2,14 +2,6 @@ package upstream
import "time" import "time"
// defaultBranchCacheTimeout specifies the timeout for the default branch cache. It can be quite long.
var defaultBranchCacheTimeout = 15 * time.Minute
// branchExistenceCacheTimeout specifies the timeout for the branch timestamp & existence cache. It should be shorter
// than fileCacheTimeout, as that gets invalidated if the branch timestamp has changed. That way, repo changes will be
// picked up faster, while still allowing the content to be cached longer if nothing changes.
var branchExistenceCacheTimeout = 5 * time.Minute
// fileCacheTimeout specifies the timeout for the file content cache - you might want to make this quite long, depending // fileCacheTimeout specifies the timeout for the file content cache - you might want to make this quite long, depending
// on your available memory. // on your available memory.
// TODO: move as option into cache interface // TODO: move as option into cache interface

View file

@ -5,46 +5,27 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"time"
"codeberg.org/codeberg/pages/server/cache"
"codeberg.org/codeberg/pages/server/gitea" "codeberg.org/codeberg/pages/server/gitea"
) )
type branchTimestamp struct {
Branch string
Timestamp time.Time
}
// GetBranchTimestamp finds the default branch (if branch is "") and returns the last modification time of the branch // GetBranchTimestamp finds the default branch (if branch is "") and returns the last modification time of the branch
// (or nil if the branch doesn't exist) // (or nil if the branch doesn't exist)
func GetBranchTimestamp(giteaClient *gitea.Client, owner, repo, branch string, branchTimestampCache cache.SetGetKey) *branchTimestamp { func GetBranchTimestamp(giteaClient *gitea.Client, owner, repo, branch string) *gitea.BranchTimestamp {
if result, ok := branchTimestampCache.Get(owner + "/" + repo + "/" + branch); ok {
if result == nil {
return nil
}
return result.(*branchTimestamp)
}
result := &branchTimestamp{
Branch: branch,
}
if len(branch) == 0 { if len(branch) == 0 {
// Get default branch // Get default branch
defaultBranch, err := giteaClient.GiteaGetRepoDefaultBranch(owner, repo) defaultBranch, err := giteaClient.GiteaGetRepoDefaultBranch(owner, repo)
if err != nil { if err != nil {
_ = branchTimestampCache.Set(owner+"/"+repo+"/", nil, defaultBranchCacheTimeout)
return nil return nil
} }
result.Branch = defaultBranch branch = defaultBranch
} }
timestamp, err := giteaClient.GiteaGetRepoBranchTimestamp(owner, repo, result.Branch) timestamp, err := giteaClient.GiteaGetRepoBranchTimestamp(owner, repo, branch)
if err != nil { if err != nil {
return nil return nil
} }
result.Timestamp = timestamp return timestamp
_ = branchTimestampCache.Set(owner+"/"+repo+"/"+branch, result, branchExistenceCacheTimeout)
return result
} }
func (o *Options) getMimeTypeByExtension() string { func (o *Options) getMimeTypeByExtension() string {

View file

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net/http"
"strings" "strings"
"time" "time"
@ -12,7 +13,6 @@ import (
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"codeberg.org/codeberg/pages/html" "codeberg.org/codeberg/pages/html"
"codeberg.org/codeberg/pages/server/cache"
"codeberg.org/codeberg/pages/server/gitea" "codeberg.org/codeberg/pages/server/gitea"
) )
@ -43,12 +43,12 @@ type Options struct {
} }
// Upstream requests a file from the Gitea API at GiteaRoot and writes it to the request context. // Upstream requests a file from the Gitea API at GiteaRoot and writes it to the request context.
func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client, branchTimestampCache, fileResponseCache cache.SetGetKey) (final bool) { func (o *Options) Upstream(ctx *http.Response, giteaClient *gitea.Client) (final bool) {
log := log.With().Strs("upstream", []string{o.TargetOwner, o.TargetRepo, o.TargetBranch, o.TargetPath}).Logger() log := log.With().Strs("upstream", []string{o.TargetOwner, o.TargetRepo, o.TargetBranch, o.TargetPath}).Logger()
// Check if the branch exists and when it was modified // Check if the branch exists and when it was modified
if o.BranchTimestamp.IsZero() { if o.BranchTimestamp.IsZero() {
branch := GetBranchTimestamp(giteaClient, o.TargetOwner, o.TargetRepo, o.TargetBranch, branchTimestampCache) branch := GetBranchTimestamp(giteaClient, o.TargetOwner, o.TargetRepo, o.TargetBranch)
if branch == nil { if branch == nil {
html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency) html.ReturnErrorPage(ctx, fasthttp.StatusFailedDependency)
@ -93,7 +93,7 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
optionsForIndexPages.appendTrailingSlash = true optionsForIndexPages.appendTrailingSlash = true
for _, indexPage := range upstreamIndexPages { for _, indexPage := range upstreamIndexPages {
optionsForIndexPages.TargetPath = strings.TrimSuffix(o.TargetPath, "/") + "/" + indexPage optionsForIndexPages.TargetPath = strings.TrimSuffix(o.TargetPath, "/") + "/" + indexPage
if optionsForIndexPages.Upstream(ctx, giteaClient, branchTimestampCache, fileResponseCache) { if optionsForIndexPages.Upstream(ctx, giteaClient, branchTimestampCache) {
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{ _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
Exists: false, Exists: false,
}, fileCacheTimeout) }, fileCacheTimeout)
@ -104,7 +104,7 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
optionsForIndexPages.appendTrailingSlash = false optionsForIndexPages.appendTrailingSlash = false
optionsForIndexPages.redirectIfExists = strings.TrimSuffix(string(ctx.Request.URI().Path()), "/") + ".html" optionsForIndexPages.redirectIfExists = strings.TrimSuffix(string(ctx.Request.URI().Path()), "/") + ".html"
optionsForIndexPages.TargetPath = o.TargetPath + ".html" optionsForIndexPages.TargetPath = o.TargetPath + ".html"
if optionsForIndexPages.Upstream(ctx, giteaClient, branchTimestampCache, fileResponseCache) { if optionsForIndexPages.Upstream(ctx, giteaClient, branchTimestampCache) {
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{ _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
Exists: false, Exists: false,
}, fileCacheTimeout) }, fileCacheTimeout)
@ -119,7 +119,7 @@ func (o *Options) Upstream(ctx *fasthttp.RequestCtx, giteaClient *gitea.Client,
optionsForNotFoundPages.appendTrailingSlash = false optionsForNotFoundPages.appendTrailingSlash = false
for _, notFoundPage := range upstreamNotFoundPages { for _, notFoundPage := range upstreamNotFoundPages {
optionsForNotFoundPages.TargetPath = "/" + notFoundPage optionsForNotFoundPages.TargetPath = "/" + notFoundPage
if optionsForNotFoundPages.Upstream(ctx, giteaClient, branchTimestampCache, fileResponseCache) { if optionsForNotFoundPages.Upstream(ctx, giteaClient, branchTimestampCache) {
_ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{ _ = fileResponseCache.Set(uri+"?timestamp="+o.timestamp(), gitea.FileResponse{
Exists: false, Exists: false,
}, fileCacheTimeout) }, fileCacheTimeout)