|
@@ -9,7 +9,6 @@ import (
|
|
|
"io/ioutil"
|
|
|
"log"
|
|
|
"math"
|
|
|
- "mime/multipart"
|
|
|
"net/http"
|
|
|
"net/url"
|
|
|
"os"
|
|
@@ -27,11 +26,11 @@ import (
|
|
|
fsp "imuslab.com/arozos/mod/filesystem/fspermission"
|
|
|
hidden "imuslab.com/arozos/mod/filesystem/hidden"
|
|
|
metadata "imuslab.com/arozos/mod/filesystem/metadata"
|
|
|
+ "imuslab.com/arozos/mod/filesystem/upload"
|
|
|
module "imuslab.com/arozos/mod/modules"
|
|
|
prout "imuslab.com/arozos/mod/prouter"
|
|
|
"imuslab.com/arozos/mod/share"
|
|
|
storage "imuslab.com/arozos/mod/storage"
|
|
|
- user "imuslab.com/arozos/mod/user"
|
|
|
)
|
|
|
|
|
|
var (
|
|
@@ -524,75 +523,134 @@ func system_fs_handleUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- err = r.ParseMultipartForm(int64(*upload_buf) << 20)
|
|
|
+ uploadedFilepaths, err := upload.StreamUploadToDisk(userinfo, w, r)
|
|
|
if err != nil {
|
|
|
- //Filesize too big
|
|
|
- log.Println(err)
|
|
|
- sendErrorResponse(w, "File too large")
|
|
|
+ sendErrorResponse(w, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- file, handler, err := r.FormFile("file")
|
|
|
- if err != nil {
|
|
|
- log.Println("Error Retrieving File from upload by user: " + username)
|
|
|
- sendErrorResponse(w, "Unable to parse file from upload")
|
|
|
- return
|
|
|
+ //Set the ownership of file(s)
|
|
|
+ quotaFulled := false
|
|
|
+ for _, fileRealpath := range uploadedFilepaths {
|
|
|
+ //Check for storage quota
|
|
|
+ uploadFileSize := fs.GetFileSize(fileRealpath)
|
|
|
+ if !userinfo.StorageQuota.HaveSpace(uploadFileSize) {
|
|
|
+ //User storage quota fulled. Remove this file
|
|
|
+ quotaFulled = true
|
|
|
+
|
|
|
+ //Remove this file as this doesn't fit
|
|
|
+ os.Remove(fileRealpath)
|
|
|
+ } else {
|
|
|
+ userinfo.SetOwnerOfFile(fileRealpath)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- //Get upload target directory
|
|
|
- uploadTarget, _ := mv(r, "path", true)
|
|
|
- if uploadTarget == "" {
|
|
|
- sendErrorResponse(w, "Upload target cannot be empty.")
|
|
|
+ if quotaFulled {
|
|
|
+ sendErrorResponse(w, "Storage Quota Full")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- //Translate the upload target directory
|
|
|
- realUploadPath, err := userinfo.VirtualPathToRealPath(uploadTarget)
|
|
|
+ sendOK(w)
|
|
|
+ return
|
|
|
|
|
|
- if err != nil {
|
|
|
- sendErrorResponse(w, "Upload target is invalid or permission denied.")
|
|
|
- return
|
|
|
- }
|
|
|
+ /*
|
|
|
+ err = r.ParseMultipartForm(int64(*upload_buf) << 20)
|
|
|
+ if err != nil {
|
|
|
+ //Filesize too big
|
|
|
+ log.Println(err)
|
|
|
+ sendErrorResponse(w, "File too large")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- storeFilename := handler.Filename //Filename of the uploaded file
|
|
|
- destFilepath := filepath.ToSlash(filepath.Clean(realUploadPath)) + "/" + storeFilename
|
|
|
+ file, handler, err := r.FormFile("file")
|
|
|
+ if err != nil {
|
|
|
+ log.Println("Error Retrieving File from upload by user: " + username)
|
|
|
+ sendErrorResponse(w, "Unable to parse file from upload")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- if !fileExists(filepath.Dir(destFilepath)) {
|
|
|
- os.MkdirAll(filepath.Dir(destFilepath), 0755)
|
|
|
- }
|
|
|
+ //Get upload target directory
|
|
|
+ uploadTarget, _ := mv(r, "path", true)
|
|
|
+ if uploadTarget == "" {
|
|
|
+ sendErrorResponse(w, "Upload target cannot be empty.")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- //Check if the upload target is read only.
|
|
|
- accmode := userinfo.GetPathAccessPermission(uploadTarget)
|
|
|
- if accmode == "readonly" {
|
|
|
- sendErrorResponse(w, "The upload target is Read Only.")
|
|
|
- return
|
|
|
- } else if accmode == "denied" {
|
|
|
- sendErrorResponse(w, "Access Denied")
|
|
|
- return
|
|
|
- }
|
|
|
+ //Translate the upload target directory
|
|
|
+ realUploadPath, err := userinfo.VirtualPathToRealPath(uploadTarget)
|
|
|
+ if err != nil {
|
|
|
+ sendErrorResponse(w, "Upload target is invalid or permission denied.")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- //Check for storage quota
|
|
|
- uploadFileSize := handler.Size
|
|
|
- if !userinfo.StorageQuota.HaveSpace(uploadFileSize) {
|
|
|
- sendErrorResponse(w, "Storage Quota Full")
|
|
|
- return
|
|
|
- }
|
|
|
+ storeFilename := handler.Filename //Filename of the uploaded file
|
|
|
+ destFilepath := filepath.ToSlash(filepath.Clean(realUploadPath)) + "/" + storeFilename
|
|
|
|
|
|
- //Prepare the file to be created (uploaded)
|
|
|
- destination, err := os.Create(destFilepath)
|
|
|
- if err != nil {
|
|
|
- sendErrorResponse(w, err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
+ if !fileExists(filepath.Dir(destFilepath)) {
|
|
|
+ os.MkdirAll(filepath.Dir(destFilepath), 0755)
|
|
|
+ }
|
|
|
|
|
|
- defer destination.Close()
|
|
|
- defer file.Close()
|
|
|
+ //Check if the upload target is read only.
|
|
|
+ accmode := userinfo.GetPathAccessPermission(uploadTarget)
|
|
|
+ if accmode == "readonly" {
|
|
|
+ sendErrorResponse(w, "The upload target is Read Only.")
|
|
|
+ return
|
|
|
+ } else if accmode == "denied" {
|
|
|
+ sendErrorResponse(w, "Access Denied")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check for storage quota
|
|
|
+ uploadFileSize := handler.Size
|
|
|
+ if !userinfo.StorageQuota.HaveSpace(uploadFileSize) {
|
|
|
+ sendErrorResponse(w, "Storage Quota Full")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //Prepare the file to be created (uploaded)
|
|
|
+ destination, err := os.Create(destFilepath)
|
|
|
+ if err != nil {
|
|
|
+ sendErrorResponse(w, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ defer destination.Close()
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ //Move the file to destination file location
|
|
|
+ if *enable_asyncFileUpload {
|
|
|
+ //Use Async upload method
|
|
|
+ go func(r *http.Request, file multipart.File, destination *os.File, userinfo *user.User) {
|
|
|
+ //Do the file copying using a buffered reader
|
|
|
+ buf := make([]byte, *file_opr_buff)
|
|
|
+ for {
|
|
|
+ n, err := file.Read(buf)
|
|
|
+ if err != nil && err != io.EOF {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if n == 0 {
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, err := destination.Write(buf[:n]); err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Clear up buffered files
|
|
|
+ r.MultipartForm.RemoveAll()
|
|
|
+
|
|
|
+ //Set the ownership of file
|
|
|
+ userinfo.SetOwnerOfFile(destFilepath)
|
|
|
|
|
|
- //Move the file to destination file location
|
|
|
- if *enable_asyncFileUpload {
|
|
|
- //Use Async upload method
|
|
|
- go func(r *http.Request, file multipart.File, destination *os.File, userinfo *user.User) {
|
|
|
- //Do the file copying using a buffered reader
|
|
|
+ //Perform a GC afterward
|
|
|
+ runtime.GC()
|
|
|
+
|
|
|
+ }(r, file, destination, userinfo)
|
|
|
+ } else {
|
|
|
+ //Use blocking upload and move method
|
|
|
buf := make([]byte, *file_opr_buff)
|
|
|
for {
|
|
|
n, err := file.Read(buf)
|
|
@@ -615,55 +673,27 @@ func system_fs_handleUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Set the ownership of file
|
|
|
userinfo.SetOwnerOfFile(destFilepath)
|
|
|
-
|
|
|
- //Perform a GC afterward
|
|
|
- runtime.GC()
|
|
|
-
|
|
|
- }(r, file, destination, userinfo)
|
|
|
- } else {
|
|
|
- //Use blocking upload and move method
|
|
|
- buf := make([]byte, *file_opr_buff)
|
|
|
- for {
|
|
|
- n, err := file.Read(buf)
|
|
|
- if err != nil && err != io.EOF {
|
|
|
- log.Println(err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
- if n == 0 {
|
|
|
- break
|
|
|
- }
|
|
|
-
|
|
|
- if _, err := destination.Write(buf[:n]); err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- //Clear up buffered files
|
|
|
- r.MultipartForm.RemoveAll()
|
|
|
-
|
|
|
- //Set the ownership of file
|
|
|
- userinfo.SetOwnerOfFile(destFilepath)
|
|
|
- }
|
|
|
-
|
|
|
- //Finish up the upload
|
|
|
+ //Finish up the upload
|
|
|
|
|
|
- //fmt.Printf("Uploaded File: %+v\n", handler.Filename)
|
|
|
- //fmt.Printf("File Size: %+v\n", handler.Size)
|
|
|
- //fmt.Printf("MIME Header: %+v\n", handler.Header)
|
|
|
- //fmt.Println("Upload target: " + realUploadPath)
|
|
|
+ //fmt.Printf("Uploaded File: %+v\n", handler.Filename)
|
|
|
+ //fmt.Printf("File Size: %+v\n", handler.Size)
|
|
|
+ //fmt.Printf("MIME Header: %+v\n", handler.Header)
|
|
|
+ //fmt.Println("Upload target: " + realUploadPath)
|
|
|
|
|
|
- //Fnish upload. Fix the tmp filename
|
|
|
- log.Println(username + " uploaded a file: " + handler.Filename)
|
|
|
+ //Fnish upload. Fix the tmp filename
|
|
|
+ log.Println(username + " uploaded a file: " + handler.Filename)
|
|
|
|
|
|
- //Do upload finishing stuff
|
|
|
- //Perform a GC
|
|
|
- runtime.GC()
|
|
|
+ //Do upload finishing stuff
|
|
|
+ //Perform a GC
|
|
|
+ runtime.GC()
|
|
|
|
|
|
- //Completed
|
|
|
- sendOK(w)
|
|
|
+ //Completed
|
|
|
+ sendOK(w)
|
|
|
|
|
|
- return
|
|
|
+ return
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
//Validate if the copy and target process will involve file overwriting problem.
|