Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 50 additions & 84 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ type UpstreamConfig struct {
// Default: https://static.crates.io/crates
CargoDownload string `json:"cargo_download" yaml:"cargo_download"`

// Debian is the upstream APT repository base URL.
// Example: http://archive.ubuntu.com/ubuntu would get Ubuntu.
// Default: http://deb.debian.org/debian
Debian string `json:"debian" yaml:"debian"`

// Auth configures authentication for upstream registries.
// Keys are URL prefixes that are matched against request URLs.
// Example: "https://npm.pkg.github.com" matches all requests to that host.
Expand Down Expand Up @@ -378,6 +383,7 @@ func Default() *Config {
GradlePluginPortal: "https://plugins.gradle.org/m2",
Cargo: "https://index.crates.io",
CargoDownload: "https://static.crates.io/crates",
Debian: "http://deb.debian.org/debian",
},
Gradle: GradleConfig{
BuildCache: GradleBuildCacheConfig{
Expand Down Expand Up @@ -422,6 +428,21 @@ func Load(path string) (*Config, error) {
return cfg, nil
}

// setEnvString sets *dst from the named environment variable, leaving it
// untouched if the variable is unset or empty.
func setEnvString(dst *string, key string) {
if v := os.Getenv(key); v != "" {
*dst = v
}
}

// setEnvBool is setEnvString for boolean fields, parsed via envBool.
func setEnvBool(dst *bool, key string) {
if v := os.Getenv(key); v != "" {
*dst = envBool(v)
}
}

// LoadFromEnv applies environment variable overrides to a Config.
// Environment variables use the PROXY_ prefix:
// - PROXY_LISTEN
Expand All @@ -434,90 +455,35 @@ func Load(path string) (*Config, error) {
// - PROXY_LOG_FORMAT
// - PROXY_HEALTH_STORAGE_PROBE_INTERVAL
func (c *Config) LoadFromEnv() {
if v := os.Getenv("PROXY_LISTEN"); v != "" {
c.Listen = v
}
if v := os.Getenv("PROXY_BASE_URL"); v != "" {
c.BaseURL = v
}
if v := os.Getenv("PROXY_UI_URL"); v != "" {
c.UIBaseURL = v
}
if v := os.Getenv("PROXY_STORAGE_URL"); v != "" {
c.Storage.URL = v
}
if v := os.Getenv("PROXY_STORAGE_PATH"); v != "" {
c.Storage.Path = v
}
if v := os.Getenv("PROXY_STORAGE_MAX_SIZE"); v != "" {
c.Storage.MaxSize = v
}
if v := os.Getenv("PROXY_STORAGE_DIRECT_SERVE"); v != "" {
c.Storage.DirectServe = envBool(v)
}
if v := os.Getenv("PROXY_STORAGE_DIRECT_SERVE_TTL"); v != "" {
c.Storage.DirectServeTTL = v
}
if v := os.Getenv("PROXY_STORAGE_DIRECT_SERVE_BASE_URL"); v != "" {
c.Storage.DirectServeBaseURL = v
}
if v := os.Getenv("PROXY_DATABASE_DRIVER"); v != "" {
c.Database.Driver = v
}
if v := os.Getenv("PROXY_DATABASE_PATH"); v != "" {
c.Database.Path = v
}
if v := os.Getenv("PROXY_DATABASE_URL"); v != "" {
c.Database.URL = v
}
if v := os.Getenv("PROXY_LOG_LEVEL"); v != "" {
c.Log.Level = v
}
if v := os.Getenv("PROXY_LOG_FORMAT"); v != "" {
c.Log.Format = v
}
if v := os.Getenv("PROXY_UPSTREAM_MAVEN"); v != "" {
c.Upstream.Maven = v
}
if v := os.Getenv("PROXY_UPSTREAM_GRADLE_PLUGIN_PORTAL"); v != "" {
c.Upstream.GradlePluginPortal = v
}
if v := os.Getenv("PROXY_COOLDOWN_DEFAULT"); v != "" {
c.Cooldown.Default = v
}
if v := os.Getenv("PROXY_CACHE_METADATA"); v != "" {
c.CacheMetadata = envBool(v)
}
if v := os.Getenv("PROXY_MIRROR_API"); v != "" {
c.MirrorAPI = envBool(v)
}
if v := os.Getenv("PROXY_METADATA_TTL"); v != "" {
c.MetadataTTL = v
}
if v := os.Getenv("PROXY_METADATA_MAX_SIZE"); v != "" {
c.MetadataMaxSize = v
}
if v := os.Getenv("PROXY_HTTP_TIMEOUT"); v != "" {
c.HTTPTimeout = v
}
if v := os.Getenv("PROXY_GRADLE_BUILD_CACHE_READ_ONLY"); v != "" {
c.Gradle.BuildCache.ReadOnly = v == "true" || v == "1"
}
if v := os.Getenv("PROXY_GRADLE_BUILD_CACHE_MAX_UPLOAD_SIZE"); v != "" {
c.Gradle.BuildCache.MaxUploadSize = v
}
if v := os.Getenv("PROXY_GRADLE_BUILD_CACHE_MAX_AGE"); v != "" {
c.Gradle.BuildCache.MaxAge = v
}
if v := os.Getenv("PROXY_GRADLE_BUILD_CACHE_MAX_SIZE"); v != "" {
c.Gradle.BuildCache.MaxSize = v
}
if v := os.Getenv("PROXY_GRADLE_BUILD_CACHE_SWEEP_INTERVAL"); v != "" {
c.Gradle.BuildCache.SweepInterval = v
}
if v := os.Getenv("PROXY_HEALTH_STORAGE_PROBE_INTERVAL"); v != "" {
c.Health.StorageProbeInterval = v
}
setEnvString(&c.Listen, "PROXY_LISTEN")
setEnvString(&c.BaseURL, "PROXY_BASE_URL")
setEnvString(&c.UIBaseURL, "PROXY_UI_URL")
setEnvString(&c.Storage.URL, "PROXY_STORAGE_URL")
setEnvString(&c.Storage.Path, "PROXY_STORAGE_PATH")
setEnvString(&c.Storage.MaxSize, "PROXY_STORAGE_MAX_SIZE")
setEnvBool(&c.Storage.DirectServe, "PROXY_STORAGE_DIRECT_SERVE")
setEnvString(&c.Storage.DirectServeTTL, "PROXY_STORAGE_DIRECT_SERVE_TTL")
setEnvString(&c.Storage.DirectServeBaseURL, "PROXY_STORAGE_DIRECT_SERVE_BASE_URL")
setEnvString(&c.Database.Driver, "PROXY_DATABASE_DRIVER")
setEnvString(&c.Database.Path, "PROXY_DATABASE_PATH")
setEnvString(&c.Database.URL, "PROXY_DATABASE_URL")
setEnvString(&c.Log.Level, "PROXY_LOG_LEVEL")
setEnvString(&c.Log.Format, "PROXY_LOG_FORMAT")
setEnvString(&c.Upstream.Maven, "PROXY_UPSTREAM_MAVEN")
setEnvString(&c.Upstream.GradlePluginPortal, "PROXY_UPSTREAM_GRADLE_PLUGIN_PORTAL")
setEnvString(&c.Upstream.Debian, "PROXY_UPSTREAM_DEBIAN")
setEnvString(&c.Cooldown.Default, "PROXY_COOLDOWN_DEFAULT")
setEnvBool(&c.CacheMetadata, "PROXY_CACHE_METADATA")
setEnvBool(&c.MirrorAPI, "PROXY_MIRROR_API")
setEnvString(&c.MetadataTTL, "PROXY_METADATA_TTL")
setEnvString(&c.MetadataMaxSize, "PROXY_METADATA_MAX_SIZE")
setEnvString(&c.HTTPTimeout, "PROXY_HTTP_TIMEOUT")
setEnvBool(&c.Gradle.BuildCache.ReadOnly, "PROXY_GRADLE_BUILD_CACHE_READ_ONLY")
setEnvString(&c.Gradle.BuildCache.MaxUploadSize, "PROXY_GRADLE_BUILD_CACHE_MAX_UPLOAD_SIZE")
setEnvString(&c.Gradle.BuildCache.MaxAge, "PROXY_GRADLE_BUILD_CACHE_MAX_AGE")
setEnvString(&c.Gradle.BuildCache.MaxSize, "PROXY_GRADLE_BUILD_CACHE_MAX_SIZE")
setEnvString(&c.Gradle.BuildCache.SweepInterval, "PROXY_GRADLE_BUILD_CACHE_SWEEP_INTERVAL")
setEnvString(&c.Health.StorageProbeInterval, "PROXY_HEALTH_STORAGE_PROBE_INTERVAL")
}

// validateAbsoluteURL returns an error if value is not a parseable URL with
Expand Down
7 changes: 7 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func TestDefault(t *testing.T) {
if cfg.Upstream.GradlePluginPortal != "https://plugins.gradle.org/m2" {
t.Errorf("Upstream.GradlePluginPortal = %q, want %q", cfg.Upstream.GradlePluginPortal, "https://plugins.gradle.org/m2")
}
if cfg.Upstream.Debian != "http://deb.debian.org/debian" {
t.Errorf("Upstream.Debian = %q, want %q", cfg.Upstream.Debian, "http://deb.debian.org/debian")
}
}

func TestValidate(t *testing.T) {
Expand Down Expand Up @@ -273,6 +276,7 @@ func TestLoadFromEnv(t *testing.T) {
t.Setenv("PROXY_LOG_LEVEL", testLevelDebug)
t.Setenv("PROXY_UPSTREAM_MAVEN", "https://maven.example.com/repository/maven-public")
t.Setenv("PROXY_UPSTREAM_GRADLE_PLUGIN_PORTAL", "https://plugins.example.com/m2")
t.Setenv("PROXY_UPSTREAM_DEBIAN", "http://archive.ubuntu.com/ubuntu")
t.Setenv("PROXY_GRADLE_BUILD_CACHE_READ_ONLY", "true")
t.Setenv("PROXY_GRADLE_BUILD_CACHE_MAX_UPLOAD_SIZE", "32MB")
t.Setenv("PROXY_GRADLE_BUILD_CACHE_MAX_AGE", "12h")
Expand Down Expand Up @@ -302,6 +306,9 @@ func TestLoadFromEnv(t *testing.T) {
if cfg.Upstream.GradlePluginPortal != "https://plugins.example.com/m2" {
t.Errorf("Upstream.GradlePluginPortal = %q, want %q", cfg.Upstream.GradlePluginPortal, "https://plugins.example.com/m2")
}
if cfg.Upstream.Debian != "http://archive.ubuntu.com/ubuntu" {
t.Errorf("Upstream.Debian = %q, want %q", cfg.Upstream.Debian, "http://archive.ubuntu.com/ubuntu")
}
if !cfg.Gradle.BuildCache.ReadOnly {
t.Error("Gradle.BuildCache.ReadOnly = false, want true")
}
Expand Down
7 changes: 5 additions & 2 deletions internal/handler/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ type DebianHandler struct {
}

// NewDebianHandler creates a new Debian/APT protocol handler.
func NewDebianHandler(proxy *Proxy, proxyURL string) *DebianHandler {
func NewDebianHandler(proxy *Proxy, proxyURL string, upstreamURL string) *DebianHandler {
if upstreamURL == "" {
upstreamURL = debianUpstream
}
return &DebianHandler{
proxy: proxy,
upstreamURL: debianUpstream,
upstreamURL: strings.TrimSuffix(upstreamURL, "/"),
proxyURL: strings.TrimSuffix(proxyURL, "/"),
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/handler/debian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ func TestDebianHandler_parsePoolPath(t *testing.T) {
}

func TestDebianHandler_Routes(t *testing.T) {
h := NewDebianHandler(nil, "http://localhost:8080")
h := NewDebianHandler(nil, "http://localhost:8080", "")
assertRoutesBasics(t, h.Routes(), "/dists/stable/Release", "/pool/../../../etc/passwd")
}
2 changes: 1 addition & 1 deletion internal/handler/download_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,7 @@ func TestDebianHandler_DownloadCacheMiss(t *testing.T) {
ContentType: "application/vnd.debian.binary-package",
}

h := NewDebianHandler(proxy, "http://localhost")
h := NewDebianHandler(proxy, "http://localhost", "")
srv := httptest.NewServer(h.Routes())
defer srv.Close()

Expand Down
2 changes: 1 addition & 1 deletion internal/handler/notfound_ecosystems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestArtifactDownloadUpstreamNotFoundReturns404(t *testing.T) {
handler func(p *Proxy) http.Handler
}{
{"debian", "/pool/main/n/nginx/nginx_1.18.0-6_amd64.deb",
func(p *Proxy) http.Handler { return NewDebianHandler(p, "http://localhost").Routes() }},
func(p *Proxy) http.Handler { return NewDebianHandler(p, "http://localhost", "").Routes() }},
{"rpm", "/releases/39/Everything/x86_64/os/Packages/n/nginx-1.24.0-1.fc39.x86_64.rpm",
func(p *Proxy) http.Handler { return NewRPMHandler(p, "http://localhost").Routes() }},
{"nuget", "/v3-flatcontainer/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg",
Expand Down
2 changes: 1 addition & 1 deletion internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func (s *Server) Start() error {
cranHandler := handler.NewCRANHandler(proxy, s.cfg.BaseURL)
juliaHandler := handler.NewJuliaHandler(proxy, s.cfg.BaseURL)
containerHandler := handler.NewContainerHandler(proxy, s.cfg.BaseURL)
debianHandler := handler.NewDebianHandler(proxy, s.cfg.BaseURL)
debianHandler := handler.NewDebianHandler(proxy, s.cfg.BaseURL, s.cfg.Upstream.Debian)
rpmHandler := handler.NewRPMHandler(proxy, s.cfg.BaseURL)

r.Mount("/npm", http.StripPrefix("/npm", npmHandler.Routes()))
Expand Down