package main import ( "errors" "strings" "time" "code.gitea.io/sdk/gitea" "github.com/patrickmn/go-cache" log "github.com/sirupsen/logrus" ) var ( pathCache = cache.New(1 * time.Hour, 1 * time.Hour) ) type PageCacheEntry struct { Repository *gitea.Repository Path string } func makePageCacheKey(domain, path string) string { return domain + "/" + path } func lookupRepositoryAndCache(username, reponame, host, domain, path, cname string, giteaClient *gitea.Client) (*gitea.Repository, error) { log.Debugf("Looking up repository %s/%s", username, reponame) repo, _, err := giteaClient.GetRepo(username, reponame) if err != nil { return nil, err } // Check if the CNAME file matches if cname != "" { file, _, err := giteaClient.GetFile( username, repo.Name, PagesBranch, "CNAME", false, ) if err != nil { log.Errorf("Could not verify CNAME of %s/%s: %v\n", username, repo.Name, err) return nil, err } cnameContent := strings.Trim( string(file[:]), "\n", ) if cnameContent != cname { return nil, errors.New("CNAME mismatch") } } // Cache data cnameCache.Set(host, domain, cache.DefaultExpiration) pathCache.Set( makePageCacheKey(domain, path), PageCacheEntry{ repo, path, }, cache.DefaultExpiration, ) return repo, nil } func RepoFromPath(username, host, cname, path string, giteaClient *gitea.Client) (*gitea.Repository, string, error) { domain := host // Guess the repository key := makePageCacheKey(domain, path) entry, found := pathCache.Get(key) if found { pageEntry := entry.(PageCacheEntry) return pageEntry.Repository, pageEntry.Path, nil } pathParts := strings.Split(path, "/") if len(pathParts) > 1 { log.Debugf("Trying repository %s", pathParts[0]) modifiedPath := strings.Join(pathParts[1:], "/") repo, err := lookupRepositoryAndCache( username, pathParts[0], host, domain, modifiedPath, cname, giteaClient, ) if err == nil { return repo, modifiedPath, nil } } log.Debugf("Trying repository pages") repo, err := lookupRepositoryAndCache( username, domain, host, domain, path, cname, giteaClient, ) return repo, path, err }