diff --git a/api.go b/api.go index 41edc4f4c5..9e094231b5 100644 --- a/api.go +++ b/api.go @@ -101,7 +101,7 @@ func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Reque if err != nil { return err } - status, err := auth.Login(authConfig, srv.HTTPRequestFactory()) + status, err := auth.Login(authConfig, srv.HTTPRequestFactory(nil)) if err != nil { return err } @@ -399,7 +399,13 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht } sf := utils.NewStreamFormatter(version > 1.0) if image != "" { //pull - if err := srv.ImagePull(image, tag, w, sf, &auth.AuthConfig{}, version > 1.3); err != nil { + metaHeaders := map[string][]string{} + for k, v := range r.Header { + if strings.HasPrefix(k, "X-Meta-") { + metaHeaders[k] = v + } + } + if err := srv.ImagePull(image, tag, w, sf, &auth.AuthConfig{}, metaHeaders, version > 1.3); err != nil { if sf.Used() { w.Write(sf.FormatError(err)) return nil @@ -468,6 +474,12 @@ func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *ht func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { authConfig := &auth.AuthConfig{} + metaHeaders := map[string][]string{} + for k, v := range r.Header { + if strings.HasPrefix(k, "X-Meta-") { + metaHeaders[k] = v + } + } if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil { return err } @@ -483,7 +495,7 @@ func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http w.Header().Set("Content-Type", "application/json") } sf := utils.NewStreamFormatter(version > 1.0) - if err := srv.ImagePush(name, w, sf, authConfig); err != nil { + if err := srv.ImagePush(name, w, sf, authConfig, metaHeaders); err != nil { if sf.Used() { w.Write(sf.FormatError(err)) return nil diff --git a/buildfile.go b/buildfile.go index 64c4503c9a..4c8db2c60e 100644 --- a/buildfile.go +++ b/buildfile.go @@ -56,7 +56,7 @@ func (b *buildFile) CmdFrom(name string) error { if err != nil { if b.runtime.graph.IsNotExist(err) { remote, tag := utils.ParseRepositoryTag(name) - if err := b.srv.ImagePull(remote, tag, b.out, utils.NewStreamFormatter(false), nil, true); err != nil { + if err := b.srv.ImagePull(remote, tag, b.out, utils.NewStreamFormatter(false), nil, nil, true); err != nil { return err } image, err = b.runtime.repositories.LookupImage(name) diff --git a/server.go b/server.go index fc41424827..646cb44877 100644 --- a/server.go +++ b/server.go @@ -102,7 +102,7 @@ func (srv *Server) ContainerExport(name string, out io.Writer) error { } func (srv *Server) ImagesSearch(term string) ([]APISearch, error) { - r, err := registry.NewRegistry(srv.runtime.root, nil, srv.HTTPRequestFactory()) + r, err := registry.NewRegistry(srv.runtime.root, nil, srv.HTTPRequestFactory(nil)) if err != nil { return nil, err } @@ -632,8 +632,8 @@ func (srv *Server) poolRemove(kind, key string) error { return nil } -func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, parallel bool) error { - r, err := registry.NewRegistry(srv.runtime.root, authConfig, srv.HTTPRequestFactory()) +func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string, parallel bool) error { + r, err := registry.NewRegistry(srv.runtime.root, authConfig, srv.HTTPRequestFactory(metaHeaders)) if err != nil { return err } @@ -780,7 +780,7 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID, } // FIXME: Allow to interrupt current push when new push of same image is done. -func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig) error { +func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string) error { if err := srv.poolAdd("push", localName); err != nil { return err } @@ -794,7 +794,7 @@ func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFo out = utils.NewWriteFlusher(out) img, err := srv.runtime.graph.Get(localName) - r, err2 := registry.NewRegistry(srv.runtime.root, authConfig, srv.HTTPRequestFactory()) + r, err2 := registry.NewRegistry(srv.runtime.root, authConfig, srv.HTTPRequestFactory(metaHeaders)) if err2 != nil { return err2 } @@ -1267,10 +1267,13 @@ func NewServer(flGraphPath string, autoRestart, enableCors bool, dns ListOpts) ( return srv, nil } -func (srv *Server) HTTPRequestFactory() *utils.HTTPRequestFactory { +func (srv *Server) HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory { if srv.reqFactory == nil { ud := utils.NewHTTPUserAgentDecorator(srv.versionInfos()...) - factory := utils.NewHTTPRequestFactory(ud) + md := &utils.HTTPMetaHeadersDecorator{ + Headers: metaHeaders, + } + factory := utils.NewHTTPRequestFactory(ud, md) srv.reqFactory = factory } return srv.reqFactory diff --git a/utils/http.go b/utils/http.go index 8c1e4b7a79..1332ce816d 100644 --- a/utils/http.go +++ b/utils/http.go @@ -93,6 +93,20 @@ func (self *HTTPUserAgentDecorator) ChangeRequest(req *http.Request) (newReq *ht return req, nil } +type HTTPMetaHeadersDecorator struct { + Headers map[string][]string +} + +func (self *HTTPMetaHeadersDecorator) ChangeRequest(req *http.Request) (newReq *http.Request, err error) { + if self.Headers == nil { + return req, nil + } + for k, v := range self.Headers { + req.Header[k] = v + } + return req, nil +} + // HTTPRequestFactory creates an HTTP request // and applies a list of decorators on the request. type HTTPRequestFactory struct {