github.com/a4a881d4/docker@v1.9.0-rc2/api/server/router/local/copy.go (about) 1 package local 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 "golang.org/x/net/context" 15 ) 16 17 // postContainersCopy is deprecated in favor of getContainersArchive. 18 func (s *router) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 19 if vars == nil { 20 return fmt.Errorf("Missing parameter") 21 } 22 23 if err := httputils.CheckForJSON(r); err != nil { 24 return err 25 } 26 27 cfg := types.CopyConfig{} 28 if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil { 29 return err 30 } 31 32 if cfg.Resource == "" { 33 return fmt.Errorf("Path cannot be empty") 34 } 35 36 data, err := s.daemon.ContainerCopy(vars["name"], cfg.Resource) 37 if err != nil { 38 if strings.Contains(strings.ToLower(err.Error()), "no such id") { 39 w.WriteHeader(http.StatusNotFound) 40 return nil 41 } 42 if os.IsNotExist(err) { 43 return fmt.Errorf("Could not find the file %s in container %s", cfg.Resource, vars["name"]) 44 } 45 return err 46 } 47 defer data.Close() 48 49 w.Header().Set("Content-Type", "application/x-tar") 50 if _, err := io.Copy(w, data); err != nil { 51 return err 52 } 53 54 return nil 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 *router) 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.daemon.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 *router) 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.daemon.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 *router) 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.daemon.ContainerExtractToDir(v.Name, v.Path, noOverwriteDirNonDir, r.Body) 116 }