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