summaryrefslogtreecommitdiff
path: root/http/uploads.go
diff options
context:
space:
mode:
Diffstat (limited to 'http/uploads.go')
-rw-r--r--http/uploads.go73
1 files changed, 59 insertions, 14 deletions
diff --git a/http/uploads.go b/http/uploads.go
index 1b851e6e..370e73e6 100644
--- a/http/uploads.go
+++ b/http/uploads.go
@@ -3,12 +3,30 @@ package http
import (
"mime/multipart"
"encoding/json"
- "log"
"strings"
"net/http"
"io/ioutil"
"io"
"sync"
+ "os"
+ "fmt"
+)
+
+const (
+ // There is no error, the file uploaded with success.
+ UploadErrorOK = 0
+
+ // No file was uploaded.
+ UploadErrorNoFile = 4
+
+ // Missing a temporary folder.
+ UploadErrorNoTmpDir = 5
+
+ // Failed to write file to disk.
+ UploadErrorCantWrite = 6
+
+ // ForbidUploads file extension.
+ UploadErrorExtension = 7
)
// FileUpload represents singular file wrapUpload.
@@ -17,46 +35,56 @@ type FileUpload struct {
Name string `json:"name"`
// MimeType contains mime-type provided by the client.
- MimeType string `json:"mimetype"`
+ MimeType string `json:"type"`
// Size of the uploaded file.
Size int64 `json:"size"`
// Error indicates file upload error (if any). See http://php.net/manual/en/features.file-upload.errors.php
- Error int
+ Error int `json:"error"`
// TempFilename points to temporary file location.
- TempFilename string `json:"tempFilename"`
+ TempFilename string `json:"tmpName"`
// associated file header
header *multipart.FileHeader
}
-func (f *FileUpload) Open(tmpDir string) error {
+func (f *FileUpload) Open(cfg *Config) error {
+ if cfg.Forbidden(f.Name) {
+ f.Error = UploadErrorExtension
+ return nil
+ }
+
file, err := f.header.Open()
if err != nil {
+ f.Error = UploadErrorNoFile
return err
}
-
defer file.Close()
- tmp, err := ioutil.TempFile(tmpDir, "upload")
+ tmp, err := ioutil.TempFile(cfg.TmpDir, "upload")
if err != nil {
+ // most likely cause of this issue is missing tmp dir
+ f.Error = UploadErrorNoTmpDir
return err
}
f.TempFilename = tmp.Name()
defer tmp.Close()
- f.Size, err = io.Copy(tmp, file)
+ if f.Size, err = io.Copy(tmp, file); err != nil {
+ f.Error = UploadErrorCantWrite
+ }
+
return err
}
func wrapUpload(f *multipart.FileHeader) *FileUpload {
- log.Print(f.Header)
return &FileUpload{
Name: f.Filename,
MimeType: f.Header.Get("Content-Type"),
+ Error: UploadErrorOK,
header: f,
}
}
@@ -119,26 +147,29 @@ func (u *Uploads) MarshalJSON() ([]byte, error) {
return json.Marshal(u.tree)
}
-// OpenUploads moves all uploaded files to temp directory, return error in case of issue with temp directory. File errors
+// Open moves all uploaded files to temp directory, return error in case of issue with temp directory. File errors
// will be handled individually. @todo: do we need it?
-func (u *Uploads) OpenUploads(tmpDir string) error {
+func (u *Uploads) Open(cfg *Config) error {
var wg sync.WaitGroup
for _, f := range u.list {
wg.Add(1)
go func(f *FileUpload) {
defer wg.Done()
- f.Open(tmpDir)
+ f.Open(cfg)
}(f)
}
wg.Wait()
- log.Print(u.list)
return nil
}
// Clear deletes all temporary files.
func (u *Uploads) Clear() {
-
+ for _, f := range u.list {
+ if f.TempFilename != "" && exists(f.TempFilename) {
+ os.Remove(f.TempFilename)
+ }
+ }
}
// parse incoming dataTree request into JSON (including multipart form dataTree)
@@ -160,3 +191,17 @@ func parseUploads(r *http.Request) (*Uploads, error) {
return u, nil
}
+
+// exists if file exists. by osutils; todo: better?
+func exists(path string) bool {
+ _, err := os.Stat(path)
+ if err == nil {
+ return true
+ }
+
+ if os.IsNotExist(err) {
+ return false
+ }
+
+ panic(fmt.Errorf("unable to stat path %q; %v", path, err))
+}