mirror of
https://github.com/distribution/distribution.git
synced 2025-08-20 07:45:33 +00:00
support mutil proxy from X-Remote-Repo-Url header
This commit is contained in:
parent
b2ae9e398c
commit
d03d55effc
2
Makefile
2
Makefile
@ -60,7 +60,7 @@ version/version.go:
|
|||||||
|
|
||||||
bin/%: cmd/% FORCE ## build individual binary
|
bin/%: cmd/% FORCE ## build individual binary
|
||||||
@echo "$(WHALE) $@${BINARY_SUFFIX}"
|
@echo "$(WHALE) $@${BINARY_SUFFIX}"
|
||||||
@go build -buildmode=pie ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@${BINARY_SUFFIX} ${GO_LDFLAGS} --ldflags '-extldflags "-Wl,-z,now" -s' ${GO_TAGS} ./$<
|
@go build -ldflags "-s -w" -trimpath -buildmode=pie ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@${BINARY_SUFFIX} ${GO_LDFLAGS} --ldflags '-extldflags "-Wl,-z,now" -s' ${GO_TAGS} ./$<
|
||||||
|
|
||||||
binaries: $(BINARIES) ## build binaries
|
binaries: $(BINARIES) ## build binaries
|
||||||
@echo "$(WHALE) $@"
|
@echo "$(WHALE) $@"
|
||||||
|
@ -670,83 +670,97 @@ func (app *App) dispatcher(dispatch dispatchFunc) http.Handler {
|
|||||||
w.Header().Add(headerName, value)
|
w.Header().Add(headerName, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
contextLocal := app.context(w, r)
|
||||||
context := app.context(w, r)
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// Automated error response handling here. Handlers may return their
|
// Automated error response handling here. Handlers may return their
|
||||||
// own errors if they need different behavior (such as range errors
|
// own errors if they need different behavior (such as range errors
|
||||||
// for layer upload).
|
// for layer upload).
|
||||||
if context.Errors.Len() > 0 {
|
if contextLocal.Errors.Len() > 0 {
|
||||||
_ = errcode.ServeJSON(w, context.Errors)
|
_ = errcode.ServeJSON(w, contextLocal.Errors)
|
||||||
app.logError(context, context.Errors)
|
app.logError(contextLocal, contextLocal.Errors)
|
||||||
} else if status, ok := context.Value("http.response.status").(int); ok && status >= 200 && status <= 399 {
|
} else if status, ok := contextLocal.Value("http.response.status").(int); ok && status >= 200 && status <= 399 {
|
||||||
dcontext.GetResponseLogger(context).Infof("response completed")
|
dcontext.GetResponseLogger(contextLocal).Infof("response completed")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := app.authorized(w, r, context); err != nil {
|
if err := app.authorized(w, r, contextLocal); err != nil {
|
||||||
dcontext.GetLogger(context).Warnf("error authorizing context: %v", err)
|
dcontext.GetLogger(contextLocal).Warnf("error authorizing context: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add username to request logging
|
// Add username to request logging
|
||||||
context.Context = dcontext.WithLogger(context.Context, dcontext.GetLogger(context.Context, userNameKey))
|
contextLocal.Context = dcontext.WithLogger(contextLocal.Context, dcontext.GetLogger(contextLocal.Context, userNameKey))
|
||||||
|
|
||||||
// sync up context on the request.
|
// sync up context on the request.
|
||||||
r = r.WithContext(context)
|
r = r.WithContext(contextLocal)
|
||||||
|
|
||||||
if app.nameRequired(r) {
|
if app.nameRequired(r) {
|
||||||
nameRef, err := reference.WithName(getName(context))
|
diyRemoteUrlValue := ""
|
||||||
|
diyRemoteUrlHeader := http.CanonicalHeaderKey("X-Remote-Repo-Url")
|
||||||
|
diyRemoteUrlHeaders, ok := r.Header[diyRemoteUrlHeader]
|
||||||
|
cc := context.Background()
|
||||||
|
if ok {
|
||||||
|
diyRemoteUrlValue = diyRemoteUrlHeaders[0]
|
||||||
|
app.Config.Proxy.RemoteURL = diyRemoteUrlValue
|
||||||
|
cc = context.WithValue(contextLocal, "ProxyRemoteURL", app.Config.Proxy.RemoteURL)
|
||||||
|
|
||||||
|
}
|
||||||
|
nameRef, err := reference.WithName(getName(contextLocal))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error parsing reference from context: %v", err)
|
dcontext.GetLogger(contextLocal).Errorf("error parsing reference from context: %v", err)
|
||||||
context.Errors = append(context.Errors, distribution.ErrRepositoryNameInvalid{
|
contextLocal.Errors = append(contextLocal.Errors, distribution.ErrRepositoryNameInvalid{
|
||||||
Name: getName(context),
|
Name: getName(contextLocal),
|
||||||
Reason: err,
|
Reason: err,
|
||||||
})
|
})
|
||||||
if err := errcode.ServeJSON(w, context.Errors); err != nil {
|
if err := errcode.ServeJSON(w, contextLocal.Errors); err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
|
dcontext.GetLogger(contextLocal).Errorf("error serving error json: %v (from %v)", err, contextLocal.Errors)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
repository, err := app.registry.Repository(context, nameRef)
|
var repository distribution.Repository
|
||||||
|
if diyRemoteUrlValue != "" {
|
||||||
|
repository, err = app.registry.Repository(cc, nameRef)
|
||||||
|
} else {
|
||||||
|
repository, err = app.registry.Repository(contextLocal, nameRef)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error resolving repository: %v", err)
|
dcontext.GetLogger(contextLocal).Errorf("error resolving repository: %v", err)
|
||||||
|
|
||||||
switch err := err.(type) {
|
switch err := err.(type) {
|
||||||
case distribution.ErrRepositoryUnknown:
|
case distribution.ErrRepositoryUnknown:
|
||||||
context.Errors = append(context.Errors, errcode.ErrorCodeNameUnknown.WithDetail(err))
|
contextLocal.Errors = append(contextLocal.Errors, errcode.ErrorCodeNameUnknown.WithDetail(err))
|
||||||
case distribution.ErrRepositoryNameInvalid:
|
case distribution.ErrRepositoryNameInvalid:
|
||||||
context.Errors = append(context.Errors, errcode.ErrorCodeNameInvalid.WithDetail(err))
|
contextLocal.Errors = append(contextLocal.Errors, errcode.ErrorCodeNameInvalid.WithDetail(err))
|
||||||
case errcode.Error:
|
case errcode.Error:
|
||||||
context.Errors = append(context.Errors, err)
|
contextLocal.Errors = append(contextLocal.Errors, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := errcode.ServeJSON(w, context.Errors); err != nil {
|
if err := errcode.ServeJSON(w, contextLocal.Errors); err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
|
dcontext.GetLogger(contextLocal).Errorf("error serving error json: %v (from %v)", err, contextLocal.Errors)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign and decorate the authorized repository with an event bridge.
|
// assign and decorate the authorized repository with an event bridge.
|
||||||
context.Repository, context.RepositoryRemover = notifications.Listen(
|
contextLocal.Repository, contextLocal.RepositoryRemover = notifications.Listen(
|
||||||
repository,
|
repository,
|
||||||
context.App.repoRemover,
|
contextLocal.App.repoRemover,
|
||||||
app.eventBridge(context, r))
|
app.eventBridge(contextLocal, r))
|
||||||
|
|
||||||
context.Repository, err = applyRepoMiddleware(app, context.Repository, app.Config.Middleware["repository"])
|
contextLocal.Repository, err = applyRepoMiddleware(app, contextLocal.Repository, app.Config.Middleware["repository"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error initializing repository middleware: %v", err)
|
dcontext.GetLogger(contextLocal).Errorf("error initializing repository middleware: %v", err)
|
||||||
context.Errors = append(context.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
|
contextLocal.Errors = append(contextLocal.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
|
||||||
|
|
||||||
if err := errcode.ServeJSON(w, context.Errors); err != nil {
|
if err := errcode.ServeJSON(w, contextLocal.Errors); err != nil {
|
||||||
dcontext.GetLogger(context).Errorf("error serving error json: %v (from %v)", err, context.Errors)
|
dcontext.GetLogger(contextLocal).Errorf("error serving error json: %v (from %v)", err, contextLocal.Errors)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(context, r).ServeHTTP(w, r)
|
dispatch(contextLocal, r).ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +177,12 @@ func (pr *proxyingRegistry) Repository(ctx context.Context, name reference.Named
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
remoteUrl := pr.remoteURL.String()
|
||||||
remoteRepo, err := client.NewRepository(name, pr.remoteURL.String(), tr)
|
ctxRemoteUrl := fmt.Sprint(ctx.Value("ProxyRemoteURL"))
|
||||||
|
if ctxRemoteUrl != "" {
|
||||||
|
remoteUrl = ctxRemoteUrl
|
||||||
|
}
|
||||||
|
remoteRepo, err := client.NewRepository(name, remoteUrl, tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user