mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-01-19 17:07:54 +00:00
more caching in-client
This commit is contained in:
parent
b2b22872a2
commit
a8afb372dd
11 changed files with 95 additions and 80 deletions
11
cmd/main.go
11
cmd/main.go
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
|
|
|
@ -5,3 +5,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrorNotFound = errors.New("not found")
|
var ErrorNotFound = errors.New("not found")
|
||||||
|
|
||||||
|
const (
|
||||||
|
branchTimestampCacheKeyPrefix = "branchTime"
|
||||||
|
defaultBranchCacheKeyPrefix = "defaultBranch"
|
||||||
|
)
|
||||||
|
|
|
@ -26,13 +26,13 @@ type Client struct {
|
||||||
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(), "/")
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func NewClient(giteaRoot, giteaAPIToken string, fileResponseCache cache.SetGetKe
|
||||||
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,
|
||||||
|
|
|
@ -17,13 +17,13 @@ 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(), "/")
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue