forked from mirrors/pkg-proxy
Compare commits
10 commits
e59798cb1f
...
081c30287d
| Author | SHA1 | Date | |
|---|---|---|---|
| 081c30287d | |||
|
|
f58e3552d3 |
||
|
|
cbec55cba4 |
||
|
|
da517ad8f5 |
||
|
|
2571b0aed5 |
||
|
|
57eb063464 |
||
|
|
59a510f3f5 |
||
|
|
35f26f4645 |
||
|
|
a1d028696d |
||
|
|
78325b6bf1 |
11 changed files with 115 additions and 19 deletions
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Log in to the Container registry
|
- name: Log in to the Container registry
|
||||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
|
|
@ -38,7 +38,7 @@ jobs:
|
||||||
images: ghcr.io/${{ github.repository }}
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|
|
||||||
4
go.mod
4
go.mod
|
|
@ -13,7 +13,7 @@ require (
|
||||||
github.com/git-pkgs/vulns v0.1.4
|
github.com/git-pkgs/vulns v0.1.4
|
||||||
github.com/go-chi/chi/v5 v5.2.5
|
github.com/go-chi/chi/v5 v5.2.5
|
||||||
github.com/jmoiron/sqlx v1.4.0
|
github.com/jmoiron/sqlx v1.4.0
|
||||||
github.com/lib/pq v1.12.2
|
github.com/lib/pq v1.12.3
|
||||||
github.com/prometheus/client_golang v1.23.2
|
github.com/prometheus/client_golang v1.23.2
|
||||||
github.com/prometheus/client_model v0.6.2
|
github.com/prometheus/client_model v0.6.2
|
||||||
github.com/spdx/tools-golang v0.5.7
|
github.com/spdx/tools-golang v0.5.7
|
||||||
|
|
@ -22,7 +22,7 @@ require (
|
||||||
golang.org/x/sync v0.20.0
|
golang.org/x/sync v0.20.0
|
||||||
google.golang.org/protobuf v1.36.11
|
google.golang.org/protobuf v1.36.11
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
modernc.org/sqlite v1.48.0
|
modernc.org/sqlite v1.48.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -432,8 +432,8 @@ github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3
|
||||||
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
|
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
|
||||||
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
|
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.12.2 h1:ajJNv84limnK3aPbDIhLtcjrUbqAw/5XNdkuI6KNe/Q=
|
github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ=
|
||||||
github.com/lib/pq v1.12.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE=
|
github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE=
|
||||||
|
|
@ -873,8 +873,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||||
modernc.org/sqlite v1.48.0 h1:ElZyLop3Q2mHYk5IFPPXADejZrlHu7APbpB0sF78bq4=
|
modernc.org/sqlite v1.48.2 h1:5CnW4uP8joZtA0LedVqLbZV5GD7F/0x91AXeSyjoh5c=
|
||||||
modernc.org/sqlite v1.48.0/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
|
modernc.org/sqlite v1.48.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
|
||||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/git-pkgs/proxy/internal/config/cargo"
|
"github.com/git-pkgs/proxy/internal/config/cargo"
|
||||||
|
"github.com/git-pkgs/proxy/internal/config/debian"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -247,6 +248,9 @@ func Default() *Config {
|
||||||
Cargo: cargo.Config{
|
Cargo: cargo.Config{
|
||||||
IncludeDefault: true,
|
IncludeDefault: true,
|
||||||
},
|
},
|
||||||
|
Debian: debian.Config{
|
||||||
|
IncludeDefault: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Upstream: UpstreamConfig{
|
Upstream: UpstreamConfig{
|
||||||
NPM: "https://registry.npmjs.org",
|
NPM: "https://registry.npmjs.org",
|
||||||
|
|
@ -347,6 +351,9 @@ func (c *Config) Validate() error {
|
||||||
if c.Ecosystem.Cargo.IncludeDefault {
|
if c.Ecosystem.Cargo.IncludeDefault {
|
||||||
c.Ecosystem.Cargo.Route = append(c.Ecosystem.Cargo.Route, cargo.RouteDefault)
|
c.Ecosystem.Cargo.Route = append(c.Ecosystem.Cargo.Route, cargo.RouteDefault)
|
||||||
}
|
}
|
||||||
|
if c.Ecosystem.Debian.IncludeDefault {
|
||||||
|
c.Ecosystem.Debian.Route = append(c.Ecosystem.Debian.Route, debian.RouteDefault)
|
||||||
|
}
|
||||||
|
|
||||||
if c.Listen == "" {
|
if c.Listen == "" {
|
||||||
return fmt.Errorf("listen address is required")
|
return fmt.Errorf("listen address is required")
|
||||||
|
|
@ -403,6 +410,9 @@ func (c *Config) Validate() error {
|
||||||
if err := c.Ecosystem.Cargo.Validate(); err != nil {
|
if err := c.Ecosystem.Cargo.Validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := c.Ecosystem.Debian.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
internal/config/debian/debian.go
Normal file
72
internal/config/debian/debian.go
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
package debian
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config configures routes
|
||||||
|
type Config struct {
|
||||||
|
IncludeDefault bool `json:"include_default" yaml:"include_default"`
|
||||||
|
Route []RouteConfig `json:"route" yaml:"route"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteConfig configures a route
|
||||||
|
type RouteConfig struct {
|
||||||
|
Path string `json:"path" yaml:"path"`
|
||||||
|
Upstream []UpstreamConfig `json:"upstream" yaml:"upstream"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpstreamConfig configures an upstream (source)
|
||||||
|
type UpstreamConfig struct {
|
||||||
|
Name string `json:"name" yaml:"name"`
|
||||||
|
Upstream string `json:"upstream" yaml:"upstream"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteDefault is the default route
|
||||||
|
var RouteDefault = RouteConfig{
|
||||||
|
Path: "/debian",
|
||||||
|
Upstream: []UpstreamConfig{
|
||||||
|
{
|
||||||
|
Name: "debian.org",
|
||||||
|
Upstream: "http://deb.debian.org/debian",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Validate() error {
|
||||||
|
for _, route := range c.Route {
|
||||||
|
if err := route.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RouteConfig) Validate() error {
|
||||||
|
// TODO: validate Path
|
||||||
|
|
||||||
|
if len(r.Upstream) == 0 {
|
||||||
|
return fmt.Errorf("debian route %q does not have any upstreams", r.Path)
|
||||||
|
}
|
||||||
|
if len(r.Upstream) > 1 {
|
||||||
|
return fmt.Errorf("debian route %q has multiple upstreams; this is not yet supported", r.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, upstream := range r.Upstream {
|
||||||
|
if err := upstream.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UpstreamConfig) Validate() error {
|
||||||
|
if _, err := url.Parse(u.Upstream); err != nil {
|
||||||
|
return fmt.Errorf("debian upstream upstream %q is not a valid URL", u.Upstream)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,11 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/git-pkgs/proxy/internal/config/cargo"
|
"github.com/git-pkgs/proxy/internal/config/cargo"
|
||||||
|
"github.com/git-pkgs/proxy/internal/config/debian"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ecosystem configuration (routes and upstreams)
|
// Ecosystem configuration (routes and upstreams)
|
||||||
type EcosystemConfig struct {
|
type EcosystemConfig struct {
|
||||||
Cargo cargo.Config `json:"cargo" yaml:"cargo"`
|
Cargo cargo.Config `json:"cargo" yaml:"cargo"`
|
||||||
|
Debian debian.Config `json:"debian" yaml:"debian"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ func TestCargoBuildIndexPath(t *testing.T) {
|
||||||
func TestCargoConfigEndpoint(t *testing.T) {
|
func TestCargoConfigEndpoint(t *testing.T) {
|
||||||
h := &CargoHandler{
|
h := &CargoHandler{
|
||||||
proxyURL: "http://localhost:8080",
|
proxyURL: "http://localhost:8080",
|
||||||
path: "/cargo",
|
path: "/xyzzy",
|
||||||
}
|
}
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/config.json", nil)
|
req := httptest.NewRequest(http.MethodGet, "/config.json", nil)
|
||||||
|
|
@ -65,7 +65,7 @@ func TestCargoConfigEndpoint(t *testing.T) {
|
||||||
t.Fatalf("failed to parse config: %v", err)
|
t.Fatalf("failed to parse config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedDL := "http://localhost:8080/cargo/crates/{crate}/{version}/download"
|
expectedDL := "http://localhost:8080/xyzzy/crates/{crate}/{version}/download"
|
||||||
if config.DL != expectedDL {
|
if config.DL != expectedDL {
|
||||||
t.Errorf("DL = %q, want %q", config.DL, expectedDL)
|
t.Errorf("DL = %q, want %q", config.DL, expectedDL)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/git-pkgs/proxy/internal/config/debian"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
debianUpstream = "http://deb.debian.org/debian"
|
|
||||||
debMatchCount = 4 // full match + name + version + arch
|
debMatchCount = 4 // full match + name + version + arch
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -16,19 +16,25 @@ const (
|
||||||
// It proxies requests to upstream Debian/Ubuntu repositories and caches .deb packages.
|
// It proxies requests to upstream Debian/Ubuntu repositories and caches .deb packages.
|
||||||
type DebianHandler struct {
|
type DebianHandler struct {
|
||||||
proxy *Proxy
|
proxy *Proxy
|
||||||
|
path string
|
||||||
upstreamURL string
|
upstreamURL string
|
||||||
proxyURL string
|
proxyURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDebianHandler creates a new Debian/APT protocol handler.
|
// NewDebianHandler creates a new Debian/APT protocol handler.
|
||||||
func NewDebianHandler(proxy *Proxy, proxyURL string) *DebianHandler {
|
func NewDebianHandler(proxy *Proxy, proxyURL string, cfg debian.RouteConfig) *DebianHandler {
|
||||||
return &DebianHandler{
|
return &DebianHandler{
|
||||||
proxy: proxy,
|
proxy: proxy,
|
||||||
upstreamURL: debianUpstream,
|
path: cfg.Path,
|
||||||
|
upstreamURL: cfg.Upstream[0].Upstream,
|
||||||
proxyURL: strings.TrimSuffix(proxyURL, "/"),
|
proxyURL: strings.TrimSuffix(proxyURL, "/"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *DebianHandler) Path() string {
|
||||||
|
return h.path
|
||||||
|
}
|
||||||
|
|
||||||
// Routes returns the HTTP handler for Debian requests.
|
// Routes returns the HTTP handler for Debian requests.
|
||||||
// Mount this at /debian on your router.
|
// Mount this at /debian on your router.
|
||||||
func (h *DebianHandler) Routes() http.Handler {
|
func (h *DebianHandler) Routes() http.Handler {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"github.com/git-pkgs/proxy/internal/config/debian"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDebianHandler_parsePoolPath(t *testing.T) {
|
func TestDebianHandler_parsePoolPath(t *testing.T) {
|
||||||
|
|
@ -18,6 +19,6 @@ func TestDebianHandler_parsePoolPath(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebianHandler_Routes(t *testing.T) {
|
func TestDebianHandler_Routes(t *testing.T) {
|
||||||
h := NewDebianHandler(nil, "http://localhost:8080")
|
h := NewDebianHandler(nil, "http://localhost:8080", debian.RouteDefault)
|
||||||
assertRoutesBasics(t, h.Routes(), "/dists/stable/Release", "/pool/../../../etc/passwd")
|
assertRoutesBasics(t, h.Routes(), "/dists/stable/Release", "/pool/../../../etc/passwd")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/git-pkgs/proxy/internal/config/debian"
|
||||||
"github.com/git-pkgs/proxy/internal/database"
|
"github.com/git-pkgs/proxy/internal/database"
|
||||||
"github.com/git-pkgs/proxy/internal/storage"
|
"github.com/git-pkgs/proxy/internal/storage"
|
||||||
"github.com/git-pkgs/purl"
|
"github.com/git-pkgs/purl"
|
||||||
|
|
@ -897,7 +898,7 @@ func TestDebianHandler_DownloadCacheMiss(t *testing.T) {
|
||||||
ContentType: "application/vnd.debian.binary-package",
|
ContentType: "application/vnd.debian.binary-package",
|
||||||
}
|
}
|
||||||
|
|
||||||
h := NewDebianHandler(proxy, "http://localhost")
|
h := NewDebianHandler(proxy, "http://localhost", debian.RouteDefault)
|
||||||
srv := httptest.NewServer(h.Routes())
|
srv := httptest.NewServer(h.Routes())
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,6 @@ func (s *Server) Start() error {
|
||||||
condaHandler := handler.NewCondaHandler(proxy, s.cfg.BaseURL)
|
condaHandler := handler.NewCondaHandler(proxy, s.cfg.BaseURL)
|
||||||
cranHandler := handler.NewCRANHandler(proxy, s.cfg.BaseURL)
|
cranHandler := handler.NewCRANHandler(proxy, s.cfg.BaseURL)
|
||||||
containerHandler := handler.NewContainerHandler(proxy, s.cfg.BaseURL)
|
containerHandler := handler.NewContainerHandler(proxy, s.cfg.BaseURL)
|
||||||
debianHandler := handler.NewDebianHandler(proxy, s.cfg.BaseURL)
|
|
||||||
rpmHandler := handler.NewRPMHandler(proxy, s.cfg.BaseURL)
|
rpmHandler := handler.NewRPMHandler(proxy, s.cfg.BaseURL)
|
||||||
|
|
||||||
for _, route := range s.cfg.Ecosystem.Cargo.Route {
|
for _, route := range s.cfg.Ecosystem.Cargo.Route {
|
||||||
|
|
@ -191,6 +190,12 @@ func (s *Server) Start() error {
|
||||||
s.logger.Info("mounted handler", "ecosystem", "cargo", "path", routeHandler.Path())
|
s.logger.Info("mounted handler", "ecosystem", "cargo", "path", routeHandler.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, route := range s.cfg.Ecosystem.Debian.Route {
|
||||||
|
routeHandler := handler.NewDebianHandler(proxy, s.cfg.BaseURL, route)
|
||||||
|
r.Mount(routeHandler.Path(), http.StripPrefix(routeHandler.Path(), routeHandler.Routes()))
|
||||||
|
s.logger.Info("mounted handler", "ecosystem", "debian", "path", routeHandler.Path())
|
||||||
|
}
|
||||||
|
|
||||||
r.Mount("/npm", http.StripPrefix("/npm", npmHandler.Routes()))
|
r.Mount("/npm", http.StripPrefix("/npm", npmHandler.Routes()))
|
||||||
r.Mount("/gem", http.StripPrefix("/gem", gemHandler.Routes()))
|
r.Mount("/gem", http.StripPrefix("/gem", gemHandler.Routes()))
|
||||||
r.Mount("/go", http.StripPrefix("/go", goHandler.Routes()))
|
r.Mount("/go", http.StripPrefix("/go", goHandler.Routes()))
|
||||||
|
|
@ -204,7 +209,6 @@ func (s *Server) Start() error {
|
||||||
r.Mount("/conda", http.StripPrefix("/conda", condaHandler.Routes()))
|
r.Mount("/conda", http.StripPrefix("/conda", condaHandler.Routes()))
|
||||||
r.Mount("/cran", http.StripPrefix("/cran", cranHandler.Routes()))
|
r.Mount("/cran", http.StripPrefix("/cran", cranHandler.Routes()))
|
||||||
r.Mount("/v2", http.StripPrefix("/v2", containerHandler.Routes()))
|
r.Mount("/v2", http.StripPrefix("/v2", containerHandler.Routes()))
|
||||||
r.Mount("/debian", http.StripPrefix("/debian", debianHandler.Routes()))
|
|
||||||
r.Mount("/rpm", http.StripPrefix("/rpm", rpmHandler.Routes()))
|
r.Mount("/rpm", http.StripPrefix("/rpm", rpmHandler.Routes()))
|
||||||
|
|
||||||
// Health, stats, and static endpoints
|
// Health, stats, and static endpoints
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue