98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package server
|
|
|
|
import (
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/grmrgecko/repo-sync/mirror"
|
|
)
|
|
|
|
// kindGeneric marks request paths that are not repository entry points.
|
|
const kindGeneric = "generic"
|
|
|
|
// resource is a crawlable unit derived from a request path.
|
|
type resource struct {
|
|
// Kind is a RepoType string, or kindGeneric.
|
|
Kind string
|
|
// Key uniquely identifies the resource in state and the lock map.
|
|
Key string
|
|
// Path is the repository request path (the suite directory for deb).
|
|
Path string
|
|
// Root is the request path prefix covering every file the resource
|
|
// owns; deb uses the archive root so pool requests match.
|
|
Root string
|
|
// ReqPath preserves the original request path.
|
|
ReqPath string
|
|
}
|
|
|
|
// classifyRequest maps a request path onto a crawlable resource. Only
|
|
// repository entry-point metadata registers a repository; every other path
|
|
// is generic and served on demand.
|
|
func classifyRequest(reqPath string) resource {
|
|
clean := path.Clean("/" + strings.TrimPrefix(reqPath, "/"))
|
|
base := path.Base(clean)
|
|
dir := path.Dir(clean)
|
|
|
|
// RPM repositories are identified by any repodata request.
|
|
if idx := strings.Index(clean, "/repodata/"); idx >= 0 {
|
|
root := clean[:idx]
|
|
if root == "" {
|
|
root = "/"
|
|
}
|
|
return resource{
|
|
Kind: string(mirror.RepoRPM),
|
|
Key: string(mirror.RepoRPM) + ":" + root,
|
|
Path: root,
|
|
Root: root,
|
|
ReqPath: clean,
|
|
}
|
|
}
|
|
|
|
// Apt suites are identified by their release files; the archive root
|
|
// above dists also covers the pool.
|
|
if base == "InRelease" || base == "Release" || base == "Release.gpg" {
|
|
root := dir
|
|
if idx := strings.Index(clean, "/dists/"); idx >= 0 {
|
|
root = clean[:idx]
|
|
if root == "" {
|
|
root = "/"
|
|
}
|
|
}
|
|
return resource{
|
|
Kind: string(mirror.RepoDeb),
|
|
Key: string(mirror.RepoDeb) + ":" + dir,
|
|
Path: dir,
|
|
Root: root,
|
|
ReqPath: clean,
|
|
}
|
|
}
|
|
|
|
// Pacman repositories are identified by their database file.
|
|
if strings.HasSuffix(base, ".db") {
|
|
return resource{
|
|
Kind: string(mirror.RepoArch),
|
|
Key: string(mirror.RepoArch) + ":" + dir,
|
|
Path: dir,
|
|
Root: dir,
|
|
ReqPath: clean,
|
|
}
|
|
}
|
|
|
|
// Alpine repositories are identified by their index archive.
|
|
if base == mirror.APKIndexName {
|
|
return resource{
|
|
Kind: string(mirror.RepoApk),
|
|
Key: string(mirror.RepoApk) + ":" + dir,
|
|
Path: dir,
|
|
Root: dir,
|
|
ReqPath: clean,
|
|
}
|
|
}
|
|
|
|
return resource{
|
|
Kind: kindGeneric,
|
|
Key: kindGeneric + ":" + clean,
|
|
Path: clean,
|
|
ReqPath: clean,
|
|
}
|
|
}
|