github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/upload/2_receive.go (about)

     1  package upload
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"path"
     9  
    10  	"github.com/pbberlin/tools/os/fsi/common"
    11  	"google.golang.org/appengine"
    12  	"google.golang.org/appengine/memcache"
    13  
    14  	"github.com/pbberlin/tools/net/http/loghttp"
    15  	"github.com/pbberlin/tools/net/http/tplx"
    16  	"github.com/pbberlin/tools/os/fsi"
    17  	"github.com/pbberlin/tools/os/fsi/dsfs"
    18  
    19  	"archive/zip"
    20  )
    21  
    22  func receiveUpload(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {
    23  
    24  	lg, _ := loghttp.Logger(w, r)
    25  	c := appengine.NewContext(r)
    26  
    27  	// parsing multipart before anything else
    28  	err := r.ParseMultipartForm(1024 * 1024 * 2)
    29  	if err != nil {
    30  		lg("Multipart parsing failed: %v", err)
    31  		return
    32  	}
    33  
    34  	wpf(w, tplx.ExecTplHelper(tplx.Head, map[string]interface{}{"HtmlTitle": "Receive an Upload"}))
    35  	defer wpf(w, tplx.Foot)
    36  	wpf(w, "<pre>")
    37  	defer wpf(w, "</pre>")
    38  
    39  	fields := []string{"getparam1", "mountname", "description"}
    40  	for _, v := range fields {
    41  		lg("%12v => %q", v, r.FormValue(v))
    42  	}
    43  
    44  	mountPoint := dsfs.MountPointLast()
    45  	if len(r.FormValue("mountname")) > 0 {
    46  		mountPoint = r.FormValue("mountname")
    47  	}
    48  	lg("mount point is %v", mountPoint)
    49  
    50  	fs1 := dsfs.New(
    51  		dsfs.MountName(mountPoint),
    52  		dsfs.AeContext(c),
    53  	)
    54  
    55  	// As closure, since we cannot define dsfs.dsFileSys as parameter
    56  	funcSave := func(argName string, data []byte) (error, *bytes.Buffer) {
    57  
    58  		b1 := new(bytes.Buffer)
    59  
    60  		fs1 := dsfs.New(
    61  			dsfs.MountName(mountPoint),
    62  			dsfs.AeContext(c),
    63  		)
    64  
    65  		dir, bname := fs1.SplitX(argName)
    66  
    67  		err := fs1.MkdirAll(dir, 0777)
    68  		wpf(b1, "mkdir %v - %v\n", dir, err)
    69  		if err != nil {
    70  			return err, b1
    71  		}
    72  
    73  		err = fs1.WriteFile(path.Join(dir, bname), data, 0777)
    74  		wpf(b1, "saved file content to %v - %v\n", argName, err)
    75  
    76  		return err, b1
    77  	}
    78  
    79  	ff := "filefield"
    80  
    81  	file, handler, err := r.FormFile(ff)
    82  	if err != nil {
    83  		lg("error calling FormFile from %q  => %v", ff, err)
    84  		return
    85  	}
    86  
    87  	if handler == nil {
    88  		lg("no multipart file %q", ff)
    89  	} else {
    90  		lg("extracted file %v", handler.Filename)
    91  
    92  		data, err := ioutil.ReadAll(file)
    93  		if err != nil {
    94  			lg("ReadAll on uploaded file failed: %v", err)
    95  			return
    96  		}
    97  		defer file.Close()
    98  		lg("extracted file content;  %v bytes", len(data))
    99  
   100  		newFilename := docRootDataStore + handler.Filename
   101  		ext := path.Ext(newFilename)
   102  
   103  		if ext == ".zip" {
   104  
   105  			lg("found zip - treat as dir-tree %q", newFilename)
   106  
   107  			r, err := zip.NewReader(file, int64(len(data)))
   108  			if err != nil {
   109  				lg("open as zip failed: %v", err)
   110  				return
   111  			}
   112  
   113  			for _, f := range r.File {
   114  				newFilename = docRootDataStore + f.Name
   115  
   116  				dir, bname := fs1.SplitX(newFilename)
   117  
   118  				if f.FileInfo().IsDir() {
   119  
   120  					lg("\t dir %s", newFilename)
   121  
   122  					err := fs1.MkdirAll(path.Join(dir, bname), 0777)
   123  					if err != nil {
   124  						lg("MkdirAll %v failed: %v", newFilename, err)
   125  						return
   126  					}
   127  
   128  				} else {
   129  
   130  					lg("\t file %s", newFilename)
   131  
   132  					rc, err := f.Open()
   133  					if err != nil {
   134  						return
   135  					}
   136  					defer func(rc io.ReadCloser) {
   137  						if err := rc.Close(); err != nil {
   138  							panic(err)
   139  						}
   140  					}(rc)
   141  
   142  					bts := new(bytes.Buffer)
   143  					size, err := io.Copy(bts, rc)
   144  					if err != nil {
   145  						lg("Could not copy from zipped file %v: %v", newFilename, err)
   146  						return
   147  					}
   148  
   149  					err = common.WriteFile(fsi.FileSystem(fs1), path.Join(dir, bname), bts.Bytes())
   150  
   151  					// err = fs1.WriteFile(path.Join(dir, bname), bts.Bytes(), 0777)
   152  					if err != nil {
   153  						lg("WriteFile of zipped file %v failed: %v", newFilename, err)
   154  						return
   155  					}
   156  					lg("\t  saved %v - %v Bytes", newFilename, size)
   157  
   158  				}
   159  
   160  			}
   161  
   162  		} else {
   163  
   164  			err, b2 := funcSave(newFilename, data)
   165  			lg("%s", b2)
   166  			if err != nil {
   167  				return
   168  			}
   169  
   170  		}
   171  
   172  		errMc := memcache.Flush(appengine.NewContext(r))
   173  		if errMc != nil {
   174  			lg("Error flushing memache: %v", errMc)
   175  			return
   176  		}
   177  
   178  		lg("--------------------\n")
   179  
   180  	}
   181  
   182  }