Skip to content

Commit 8811d94

Browse files
author
Prince Rachit Sinha
committed
[image-builder] Intro non-docker url rewrite
Process docker api urls starting with /v2/ differently from non-docker api url whose path does not start with /v2/.
1 parent fe904f9 commit 8811d94

File tree

1 file changed

+44
-3
lines changed
  • components/image-builder-bob/pkg/proxy

1 file changed

+44
-3
lines changed

components/image-builder-bob/pkg/proxy/proxy.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type Repo struct {
5252
Auth func() docker.Authorizer
5353
}
5454

55-
func rewriteURL(u *url.URL, fromRepo, toRepo, host, tag string) {
55+
func rewriteDockerAPIURL(u *url.URL, fromRepo, toRepo, host, tag string) {
5656
var (
5757
from = "/v2/" + strings.Trim(fromRepo, "/") + "/"
5858
to = "/v2/" + strings.Trim(toRepo, "/") + "/"
@@ -79,6 +79,27 @@ func rewriteURL(u *url.URL, fromRepo, toRepo, host, tag string) {
7979
u.Host = host
8080
}
8181

82+
// rewriteNonDockerAPIURL is used when a url has to be rewritten but the url
83+
// contains a non docker api path
84+
func rewriteNonDockerAPIURL(u *url.URL, fromPrefix, toPrefix, host, tag string) {
85+
var (
86+
from = "/" + strings.Trim(fromPrefix, "/") + "/"
87+
to = "/" + strings.Trim(toPrefix, "/") + "/"
88+
)
89+
if fromPrefix == "" {
90+
from = "/"
91+
}
92+
if toPrefix == "" {
93+
to = "/"
94+
}
95+
u.Path = to + strings.TrimPrefix(u.Path, from)
96+
97+
// we reset the escaped encoding hint, because EscapedPath will produce a valid encoding.
98+
u.RawPath = ""
99+
100+
u.Host = host
101+
}
102+
82103
// ServeHTTP serves the proxy
83104
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
84105
ctx := r.Context()
@@ -88,9 +109,20 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
88109
alias string
89110
)
90111
for k, v := range proxy.Aliases {
112+
// Docker api request
91113
if strings.HasPrefix(r.URL.Path, "/v2/"+k+"/") {
92114
repo = &v
93115
alias = k
116+
rewriteDockerAPIURL(r.URL, alias, repo.Repo, repo.Host, repo.Tag)
117+
break
118+
}
119+
// Non-Docker api request
120+
if strings.HasPrefix(r.URL.Path, "/"+k+"/") {
121+
// We will use the same repo/alias and its credentials but we will set target
122+
// repo as empty
123+
repo = &v
124+
alias = k
125+
rewriteNonDockerAPIURL(r.URL, alias, "", repo.Host, repo.Tag)
94126
break
95127
}
96128
}
@@ -99,7 +131,6 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
99131
return
100132
}
101133

102-
rewriteURL(r.URL, alias, repo.Repo, repo.Host, repo.Tag)
103134
r.Host = r.URL.Host
104135

105136
auth := repo.Auth()
@@ -186,13 +217,23 @@ func (proxy *Proxy) reverse(alias string) *httputil.ReverseProxy {
186217
rp.ModifyResponse = func(r *http.Response) error {
187218
// Some registries return a Location header which we must rewrite to still push
188219
// through this proxy.
220+
// We support only relative URLs and not absolute URLs.
189221
if loc := r.Header.Get("Location"); loc != "" {
190222
lurl, err := url.Parse(loc)
191223
if err != nil {
192224
return err
193225
}
194226

195-
rewriteURL(lurl, repo.Repo, alias, proxy.Host.Host, "")
227+
if strings.HasPrefix(loc, "/v2/") {
228+
rewriteDockerAPIURL(lurl, repo.Repo, alias, proxy.Host.Host, "")
229+
} else {
230+
// since this is a non docker api location we
231+
// do not need to process the path.
232+
// All docker api URLs always start with /v2/. See spec
233+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints
234+
rewriteNonDockerAPIURL(lurl, "", alias, repo.Host, repo.Tag)
235+
}
236+
196237
lurl.Host = proxy.Host.Host
197238
// force scheme to http assuming this proxy never runs as https
198239
lurl.Scheme = proxy.Host.Scheme

0 commit comments

Comments
 (0)