github.com/cookieai-jar/moby@v17.12.1-ce-rc2+incompatible/api/server/router/container/copy.go (about) 1 package container 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "io" 7 "net/http" 8 9 "github.com/docker/docker/api/server/httputils" 10 "github.com/docker/docker/api/types" 11 "github.com/docker/docker/api/types/versions" 12 "golang.org/x/net/context" 13 ) 14 15 type pathError struct{} 16 17 func (pathError) Error() string { 18 return "Path cannot be empty" 19 } 20 21 func (pathError) InvalidParameter() {} 22 23 // postContainersCopy is deprecated in favor of getContainersArchive. 24 func (s *containerRouter) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 25 // Deprecated since 1.8, Errors out since 1.12 26 version := httputils.VersionFromContext(ctx) 27 if versions.GreaterThanOrEqualTo(version, "1.24") { 28 w.WriteHeader(http.StatusNotFound) 29 return nil 30 } 31 if err := httputils.CheckForJSON(r); err != nil { 32 return err 33 } 34 35 cfg := types.CopyConfig{} 36 if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil { 37 return err 38 } 39 40 if cfg.Resource == "" { 41 return pathError{} 42 } 43 44 data, err := s.backend.ContainerCopy(vars["name"], cfg.Resource) 45 if err != nil { 46 return err 47 } 48 defer data.Close() 49 50 w.Header().Set("Content-Type", "application/x-tar") 51 _, err = io.Copy(w, data) 52 return err 53 } 54 55 // // Encode the stat to JSON, base64 encode, and place in a header. 56 func setContainerPathStatHeader(stat *types.ContainerPathStat, header http.Header) error { 57 statJSON, err := json.Marshal(stat) 58 if err != nil { 59 return err 60 } 61 62 header.Set( 63 "X-Docker-Container-Path-Stat", 64 base64.StdEncoding.EncodeToString(statJSON), 65 ) 66 67 return nil 68 } 69 70 func (s *containerRouter) headContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 71 v, err := httputils.ArchiveFormValues(r, vars) 72 if err != nil { 73 return err 74 } 75 76 stat, err := s.backend.ContainerStatPath(v.Name, v.Path) 77 if err != nil { 78 return err 79 } 80 81 return setContainerPathStatHeader(stat, w.Header()) 82 } 83 84 func (s *containerRouter) getContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 85 v, err := httputils.ArchiveFormValues(r, vars) 86 if err != nil { 87 return err 88 } 89 90 tarArchive, stat, err := s.backend.ContainerArchivePath(v.Name, v.Path) 91 if err != nil { 92 return err 93 } 94 defer tarArchive.Close() 95 96 if err := setContainerPathStatHeader(stat, w.Header()); err != nil { 97 return err 98 } 99 100 w.Header().Set("Content-Type", "application/x-tar") 101 _, err = io.Copy(w, tarArchive) 102 103 return err 104 } 105 106 func (s *containerRouter) putContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 107 v, err := httputils.ArchiveFormValues(r, vars) 108 if err != nil { 109 return err 110 } 111 112 noOverwriteDirNonDir := httputils.BoolValue(r, "noOverwriteDirNonDir") 113 copyUIDGID := httputils.BoolValue(r, "copyUIDGID") 114 115 return s.backend.ContainerExtractToDir(v.Name, v.Path, copyUIDGID, noOverwriteDirNonDir, r.Body) 116 }