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