-
Notifications
You must be signed in to change notification settings - Fork 9
/
upload.go
86 lines (69 loc) · 2.27 KB
/
upload.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package controllers
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/steffen25/golang.zone/util"
)
const (
MB = 1 << 20
)
type UploadController struct{}
type UploadImageResponse struct {
ImageURL string `json:"imageUrl"`
}
func NewUploadController() *UploadController {
return &UploadController{}
}
func (uc *UploadController) UploadImage(w http.ResponseWriter, r *http.Request) {
contentType := r.Header.Get("Content-type")
if !strings.Contains(contentType, "multipart/form-data") {
NewAPIError(&APIError{false, "Invalid request body. Request body must be of type multipart/form-data", http.StatusBadRequest}, w)
return
}
// Limit upload size
r.Body = http.MaxBytesReader(w, r.Body, 2*MB)
if err := r.ParseMultipartForm(2 * MB); err != nil {
NewAPIError(&APIError{false, "The file you are uploading is too big. Maximum file size is 2MB", http.StatusBadRequest}, w)
return
}
var Buf bytes.Buffer
file, _, err := r.FormFile("image")
if err != nil {
if err == http.ErrMissingFile {
NewAPIError(&APIError{false, "Image is required", http.StatusBadRequest}, w)
return
}
NewAPIError(&APIError{false, "Error processing multipart data", http.StatusBadRequest}, w)
return
}
defer file.Close()
// Copy the file data to my buffer
io.Copy(&Buf, file)
fileExtension := http.DetectContentType(Buf.Bytes())
validFileExtensions := map[string]string{
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
}
if _, ok := validFileExtensions[fileExtension]; !ok {
NewAPIError(&APIError{false, "Invalid mime type, file must be of image/jpeg, image/png or image/gif", http.StatusBadRequest}, w)
return
}
ext := validFileExtensions[fileExtension]
now := time.Now()
fileName := now.Format("2006-01-02_15-04-05") + "_" + util.GetMD5Hash(now.String())
err = ioutil.WriteFile("./public/images/"+fileName+ext, Buf.Bytes(), 0644)
if err != nil {
NewAPIError(&APIError{false, "Could not write file to disk", http.StatusInternalServerError}, w)
return
}
Buf.Reset()
// TODO: Remove hardcoded url
imageSrc := util.GetRequestScheme(r) + r.Host + "/assets/" + fileName + ext
data := UploadImageResponse{imageSrc}
NewAPIResponse(&APIResponse{Success: true, Message: "Image uploaded successfully", Data: data}, w, http.StatusOK)
}