mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-01-18 16:47:54 +00:00
Add redis for caching, first try during a train ride so expect it to not be working yet
This commit is contained in:
parent
b8b9886ee1
commit
5b6eecc75f
12 changed files with 149 additions and 32 deletions
5
go.mod
5
go.mod
|
@ -7,6 +7,7 @@ toolchain go1.21.4
|
|||
require (
|
||||
code.gitea.io/sdk/gitea v0.16.1-0.20231115014337-e23e8aa3004f
|
||||
github.com/OrlovEvgeny/go-mcache v0.0.0-20200121124330-1a8195b34f3a
|
||||
github.com/creasty/defaults v1.7.0
|
||||
github.com/go-acme/lego/v4 v4.5.3
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
|
@ -14,6 +15,7 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/microcosm-cc/bluemonday v1.0.26
|
||||
github.com/pelletier/go-toml/v2 v2.1.0
|
||||
github.com/redis/go-redis/v9 v9.5.1
|
||||
github.com/reugn/equalizer v0.0.0-20210216135016-a959c509d7ad
|
||||
github.com/rs/zerolog v1.27.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
|
@ -42,13 +44,14 @@ require (
|
|||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cloudflare/cloudflare-go v0.20.0 // indirect
|
||||
github.com/cpu/goacmedns v0.1.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/creasty/defaults v1.7.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||
github.com/deepmap/oapi-codegen v1.6.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/dnsimple/dnsimple-go v0.70.1 // indirect
|
||||
github.com/exoscale/egoscale v0.67.0 // indirect
|
||||
|
|
10
go.sum
10
go.sum
|
@ -97,6 +97,10 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
|||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
|
@ -105,6 +109,8 @@ github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
@ -143,6 +149,8 @@ github.com/deepmap/oapi-codegen v1.6.1 h1:2BvsmRb6pogGNtr8Ann+esAbSKFXx2CZN18VpA
|
|||
github.com/deepmap/oapi-codegen v1.6.1/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
|
@ -615,6 +623,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
|||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
|
||||
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/reugn/equalizer v0.0.0-20210216135016-a959c509d7ad h1:WtSUHi5zthjudjIi3L6QmL/V9vpJPbc/j/F2u55d3fs=
|
||||
|
|
4
server/cache/interface.go
vendored
4
server/cache/interface.go
vendored
|
@ -4,7 +4,7 @@ import "time"
|
|||
|
||||
// ICache is an interface that defines how the pages server interacts with the cache.
|
||||
type ICache interface {
|
||||
Set(key string, value interface{}, ttl time.Duration) error
|
||||
Get(key string) (interface{}, bool)
|
||||
Set(key string, value string, ttl time.Duration) error
|
||||
Get(key string) (string, bool)
|
||||
Remove(key string)
|
||||
}
|
||||
|
|
28
server/cache/memory.go
vendored
28
server/cache/memory.go
vendored
|
@ -1,7 +1,31 @@
|
|||
package cache
|
||||
|
||||
import "github.com/OrlovEvgeny/go-mcache"
|
||||
import (
|
||||
"github.com/OrlovEvgeny/go-mcache"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MCache struct {
|
||||
mcache *mcache.CacheDriver
|
||||
}
|
||||
|
||||
func (m *MCache) Set(key string, value string, ttl time.Duration) error {
|
||||
return m.mcache.Set(key, value, ttl)
|
||||
}
|
||||
|
||||
func (m *MCache) Get(key string) (string, bool) {
|
||||
val, ok := m.mcache.Get(key)
|
||||
if ok {
|
||||
return val.(string), true
|
||||
} else {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MCache) Remove(key string) {
|
||||
m.mcache.Remove(key)
|
||||
}
|
||||
|
||||
func NewInMemoryCache() ICache {
|
||||
return mcache.New()
|
||||
return &MCache{mcache.New()}
|
||||
}
|
||||
|
|
47
server/cache/redis.go
vendored
Normal file
47
server/cache/redis.go
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/rs/zerolog/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RedisCache struct {
|
||||
ctx context.Context
|
||||
rdb *redis.Client
|
||||
}
|
||||
|
||||
func (r *RedisCache) Set(key string, value string, ttl time.Duration) error {
|
||||
return r.rdb.Set(r.ctx, key, value, ttl).Err()
|
||||
}
|
||||
|
||||
func (r *RedisCache) Get(key string) (string, bool) {
|
||||
val, err := r.rdb.Get(r.ctx, key).Result()
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
log.Error().Err(err).Str("key", key).Msg("Couldn't request key from cache.")
|
||||
}
|
||||
return "", false
|
||||
} else {
|
||||
return val, true
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RedisCache) Remove(key string) {
|
||||
err := r.rdb.Del(r.ctx, key).Err()
|
||||
if err == nil {
|
||||
log.Error().Err(err).Str("key", key).Msg("Couldn't delete key from cache.")
|
||||
}
|
||||
}
|
||||
|
||||
func NewRedisCache() ICache {
|
||||
return &RedisCache{
|
||||
context.Background(),
|
||||
redis.NewClient(&redis.Options{
|
||||
Addr: "localhost:6379",
|
||||
Password: "", // no password set
|
||||
DB: 0, // use default DB
|
||||
}),
|
||||
}
|
||||
}
|
|
@ -60,12 +60,12 @@ func SetupHTTPACMEChallengeServer(challengeCache cache.ICache, sslPort uint) htt
|
|||
// it's an acme request
|
||||
if strings.HasPrefix(ctx.Path(), challengePath) {
|
||||
challenge, ok := challengeCache.Get(domain + "/" + strings.TrimPrefix(ctx.Path(), challengePath))
|
||||
if !ok || challenge == nil {
|
||||
if !ok || challenge == "" {
|
||||
log.Info().Msgf("HTTP-ACME challenge for '%s' failed: token not found", domain)
|
||||
ctx.String("no challenge for this token", http.StatusNotFound)
|
||||
}
|
||||
log.Info().Msgf("HTTP-ACME challenge for '%s' succeeded", domain)
|
||||
ctx.String(challenge.(string))
|
||||
ctx.String(challenge)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/OrlovEvgeny/go-mcache"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -31,7 +32,7 @@ func TLSConfig(mainDomainSuffix string,
|
|||
giteaClient *gitea.Client,
|
||||
acmeClient *AcmeClient,
|
||||
firstDefaultBranch string,
|
||||
keyCache, challengeCache, dnsLookupCache, canonicalDomainCache cache.ICache,
|
||||
keyCache *mcache.CacheDriver, challengeCache cache.ICache, dnsLookupCache *mcache.CacheDriver, canonicalDomainCache cache.ICache,
|
||||
certDB database.CertDB,
|
||||
noDNS01 bool,
|
||||
rawDomain string,
|
||||
|
@ -56,7 +57,7 @@ func TLSConfig(mainDomainSuffix string,
|
|||
if !ok {
|
||||
return nil, errors.New("no challenge for this domain")
|
||||
}
|
||||
cert, err := tlsalpn01.ChallengeCert(domain, challenge.(string))
|
||||
cert, err := tlsalpn01.ChallengeCert(domain, challenge)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"github.com/OrlovEvgeny/go-mcache"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"codeberg.org/codeberg/pages/server/cache"
|
||||
)
|
||||
|
||||
// lookupCacheTimeout specifies the timeout for the DNS lookup cache.
|
||||
|
@ -15,7 +14,7 @@ var defaultPagesRepo = "pages"
|
|||
|
||||
// GetTargetFromDNS searches for CNAME or TXT entries on the request domain ending with MainDomainSuffix.
|
||||
// If everything is fine, it returns the target data.
|
||||
func GetTargetFromDNS(domain, mainDomainSuffix, firstDefaultBranch string, dnsLookupCache cache.ICache) (targetOwner, targetRepo, targetBranch string) {
|
||||
func GetTargetFromDNS(domain, mainDomainSuffix, firstDefaultBranch string, dnsLookupCache *mcache.CacheDriver) (targetOwner, targetRepo, targetBranch string) {
|
||||
// Get CNAME or TXT
|
||||
var cname string
|
||||
var err error
|
||||
|
|
|
@ -115,8 +115,17 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
log := log.With().Str("cache_key", cacheKey).Logger()
|
||||
log.Trace().Msg("try file in cache")
|
||||
// handle if cache entry exist
|
||||
if cache, ok := client.responseCache.Get(cacheKey); ok {
|
||||
cache := cache.(FileResponse)
|
||||
if cacheMetadata, ok := client.responseCache.Get(cacheKey + "|Metadata"); ok {
|
||||
cacheMetadataParts := strings.Split(cacheMetadata, "\n")
|
||||
cache := FileResponse{
|
||||
Exists: cacheMetadataParts[0] == "true",
|
||||
IsSymlink: cacheMetadataParts[1] == "true",
|
||||
ETag: cacheMetadataParts[2],
|
||||
}
|
||||
cacheBodyString, _ := client.responseCache.Get(cacheKey + "|Body")
|
||||
cache.Body = []byte(cacheBodyString)
|
||||
// TODO: don't grab the content from the cache if the ETag matches?!
|
||||
|
||||
cachedHeader, cachedStatusCode := cache.createHttpResponse(cacheKey)
|
||||
// TODO: check against some timestamp mismatch?!?
|
||||
if cache.Exists {
|
||||
|
@ -130,6 +139,7 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
return io.NopCloser(bytes.NewReader(cache.Body)), cachedHeader, cachedStatusCode, nil
|
||||
} else if cache.IsEmpty() {
|
||||
log.Debug().Msg("[cache] is empty")
|
||||
// TODO: empty files aren't cached anyways; but when closing the issue please make sure that a missing body cache key is also handled correctly.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +174,12 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
ETag: resp.Header.Get(ETagHeader),
|
||||
}
|
||||
log.Trace().Msgf("file response has %d bytes", len(fileResponse.Body))
|
||||
if err := client.responseCache.Set(cacheKey, fileResponse, fileCacheTimeout); err != nil {
|
||||
metadataStr := strconv.FormatBool(fileResponse.Exists) + "\n" + strconv.FormatBool(fileResponse.IsSymlink) + "\n" + fileResponse.ETag
|
||||
if err := client.responseCache.Set(cacheKey+"|Metadata", metadataStr, fileCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msg("[cache] error on cache write")
|
||||
}
|
||||
// TODO: Test with binary files, as we convert []byte to string! Using []byte values might makes more sense anyways.
|
||||
if err := client.responseCache.Set(cacheKey+"|Body", string(fileResponse.Body), fileCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msg("[cache] error on cache write")
|
||||
}
|
||||
|
||||
|
@ -187,13 +202,11 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
ETag: resp.Header.Get(ETagHeader),
|
||||
MimeType: mimeType,
|
||||
}
|
||||
// TODO: dafuq...
|
||||
return fileResp.CreateCacheReader(reader, client.responseCache, cacheKey), resp.Response.Header, resp.StatusCode, nil
|
||||
|
||||
case http.StatusNotFound:
|
||||
if err := client.responseCache.Set(cacheKey, FileResponse{
|
||||
Exists: false,
|
||||
ETag: resp.Header.Get(ETagHeader),
|
||||
}, fileCacheTimeout); err != nil {
|
||||
if err := client.responseCache.Set(cacheKey+"|Metadata", "false\nfalse\n"+resp.Header.Get(ETagHeader), fileCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msg("[cache] error on cache write")
|
||||
}
|
||||
|
||||
|
@ -208,21 +221,28 @@ func (client *Client) ServeRawContent(targetOwner, targetRepo, ref, resource str
|
|||
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 {
|
||||
branchTimeStamp := stamp.(*BranchTimestamp)
|
||||
if branchTimeStamp.notFound {
|
||||
if stamp, ok := client.responseCache.Get(cacheKey); ok {
|
||||
if stamp == "" {
|
||||
log.Trace().Msgf("[cache] use branch %q not found", branchName)
|
||||
return &BranchTimestamp{}, ErrorNotFound
|
||||
}
|
||||
log.Trace().Msgf("[cache] use branch %q exist", branchName)
|
||||
return branchTimeStamp, nil
|
||||
// This comes from the refactoring of the caching library.
|
||||
// The branch as reported by the API was stored in the cache, and I'm not sure if there are
|
||||
// situations where it differs from the name in the request, hence this is left here.
|
||||
stampParts := strings.SplitN(stamp, "", 2)
|
||||
stampTime, _ := time.Parse(time.RFC3339, stampParts[0])
|
||||
return &BranchTimestamp{
|
||||
Branch: stampParts[1],
|
||||
Timestamp: stampTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
branch, resp, err := client.sdkClient.GetRepoBranch(repoOwner, repoName, branchName)
|
||||
if err != nil {
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
log.Trace().Msgf("[cache] set cache branch %q not found", branchName)
|
||||
if err := client.responseCache.Set(cacheKey, &BranchTimestamp{Branch: branchName, notFound: true}, branchExistenceCacheTimeout); err != nil {
|
||||
if err := client.responseCache.Set(cacheKey, "", branchExistenceCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msg("[cache] error on cache write")
|
||||
}
|
||||
return &BranchTimestamp{}, ErrorNotFound
|
||||
|
@ -239,7 +259,7 @@ func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchNam
|
|||
}
|
||||
|
||||
log.Trace().Msgf("set cache branch [%s] exist", branchName)
|
||||
if err := client.responseCache.Set(cacheKey, stamp, branchExistenceCacheTimeout); err != nil {
|
||||
if err := client.responseCache.Set(cacheKey, stamp.Timestamp.Format(time.RFC3339)+"|"+stamp.Branch, branchExistenceCacheTimeout); err != nil {
|
||||
log.Error().Err(err).Msg("[cache] error on cache write")
|
||||
}
|
||||
return stamp, nil
|
||||
|
@ -248,8 +268,8 @@ func (client *Client) GiteaGetRepoBranchTimestamp(repoOwner, repoName, branchNam
|
|||
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
|
||||
if branch, ok := client.responseCache.Get(cacheKey); ok {
|
||||
return branch, nil
|
||||
}
|
||||
|
||||
repo, resp, err := client.sdkClient.GetRepo(repoOwner, repoName)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/OrlovEvgeny/go-mcache"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
@ -19,7 +20,7 @@ func handleCustomDomain(log zerolog.Logger, ctx *context.Context, giteaClient *g
|
|||
trimmedHost string,
|
||||
pathElements []string,
|
||||
firstDefaultBranch string,
|
||||
dnsLookupCache, canonicalDomainCache, redirectsCache cache.ICache,
|
||||
dnsLookupCache *mcache.CacheDriver, canonicalDomainCache, redirectsCache cache.ICache,
|
||||
) {
|
||||
// Serve pages from custom domains
|
||||
targetOwner, targetRepo, targetBranch := dns.GetTargetFromDNS(trimmedHost, mainDomainSuffix, firstDefaultBranch, dnsLookupCache)
|
||||
|
|
|
@ -20,7 +20,7 @@ const canonicalDomainConfig = ".domains"
|
|||
func (o *Options) CheckCanonicalDomain(giteaClient *gitea.Client, actualDomain, mainDomainSuffix string, canonicalDomainCache cache.ICache) (domain string, valid bool) {
|
||||
// Check if this request is cached.
|
||||
if cachedValue, ok := canonicalDomainCache.Get(o.TargetOwner + "/" + o.TargetRepo + "/" + o.TargetBranch); ok {
|
||||
domains := cachedValue.([]string)
|
||||
domains := strings.Split(cachedValue, "\n")
|
||||
for _, domain := range domains {
|
||||
if domain == actualDomain {
|
||||
valid = true
|
||||
|
@ -33,6 +33,7 @@ func (o *Options) CheckCanonicalDomain(giteaClient *gitea.Client, actualDomain,
|
|||
body, err := giteaClient.GiteaRawContent(o.TargetOwner, o.TargetRepo, o.TargetBranch, canonicalDomainConfig)
|
||||
if err != nil && !errors.Is(err, gitea.ErrorNotFound) {
|
||||
log.Error().Err(err).Msgf("could not read %s of %s/%s", canonicalDomainConfig, o.TargetOwner, o.TargetRepo)
|
||||
// TODO: WTF we just continue?!
|
||||
}
|
||||
|
||||
var domains []string
|
||||
|
@ -62,7 +63,7 @@ func (o *Options) CheckCanonicalDomain(giteaClient *gitea.Client, actualDomain,
|
|||
}
|
||||
|
||||
// Add result to cache.
|
||||
_ = canonicalDomainCache.Set(o.TargetOwner+"/"+o.TargetRepo+"/"+o.TargetBranch, domains, canonicalDomainCacheTimeout)
|
||||
_ = canonicalDomainCache.Set(o.TargetOwner+"/"+o.TargetRepo+"/"+o.TargetBranch, strings.Join(domains, "\n"), canonicalDomainCacheTimeout)
|
||||
|
||||
// Return the first domain from the list and return if any of the domains
|
||||
// matched the requested domain.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package upstream
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -29,7 +30,12 @@ func (o *Options) getRedirects(giteaClient *gitea.Client, redirectsCache cache.I
|
|||
|
||||
// Check for cached redirects
|
||||
if cachedValue, ok := redirectsCache.Get(cacheKey); ok {
|
||||
redirects = cachedValue.([]Redirect)
|
||||
redirects := []Redirect{}
|
||||
err := json.Unmarshal([]byte(cachedValue), redirects)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("could not parse redirects for key %s", cacheKey)
|
||||
// It's okay to continue, the array stays empty.
|
||||
}
|
||||
} else {
|
||||
// Get _redirects file and parse
|
||||
body, err := giteaClient.GiteaRawContent(o.TargetOwner, o.TargetRepo, o.TargetBranch, redirectsConfig)
|
||||
|
@ -58,7 +64,12 @@ func (o *Options) getRedirects(giteaClient *gitea.Client, redirectsCache cache.I
|
|||
})
|
||||
}
|
||||
}
|
||||
_ = redirectsCache.Set(cacheKey, redirects, redirectsCacheTimeout)
|
||||
redirectsJson, err := json.Marshal(redirects)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("could not store redirects for key %s", cacheKey)
|
||||
} else {
|
||||
_ = redirectsCache.Set(cacheKey, string(redirectsJson), redirectsCacheTimeout)
|
||||
}
|
||||
}
|
||||
return redirects
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue