From d0da1a9114d8c5d61f95352a17c2801758f169bc Mon Sep 17 00:00:00 2001 From: tfasano1 Date: Thu, 4 May 2023 08:26:44 -0500 Subject: [PATCH] File Uploading feature by tfasano1 --- config/config.go | 5 ++++ controllers/getController.go | 7 ++++++ controllers/postController.go | 45 +++++++++++++++++++++++++++++++++++ env_example.json | 6 ++++- main.go | 9 +++++++ routes/getRoutes.go | 3 +++ routes/postRoutes.go | 1 + templates/pages/home.html | 22 ++++++++++++++++- 8 files changed, 96 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index fdf6e17..0c00e62 100644 --- a/config/config.go +++ b/config/config.go @@ -25,6 +25,11 @@ type Configuration struct { Template struct { BaseName string `json:"BaseTemplateName"` } + + Upload struct { + BaseName string `json:"UploadDirectoryName"` + MaxSize int64 `json:"MaxUploadSize"` + } } // LoadConfig loads and returns a configuration struct diff --git a/controllers/getController.go b/controllers/getController.go index c4f9a27..6a2b391 100644 --- a/controllers/getController.go +++ b/controllers/getController.go @@ -61,6 +61,13 @@ func (getController *GetController) ShowLogin(w http.ResponseWriter, r *http.Req templating.RenderTemplate(getController.App, w, "templates/pages/login.html", data) } +func (getController *GetController) ShowFile(w http.ResponseWriter, r *http.Request) { + // GET /uploads?name=file.jpg + // will serve file.jpg + name := r.URL.Query().Get("name") + http.ServeFile(w, r, getController.App.Config.Upload.BaseName+name) +} + func (getController *GetController) Logout(w http.ResponseWriter, r *http.Request) { models.LogoutUser(getController.App, w, r) http.Redirect(w, r, "/", http.StatusFound) diff --git a/controllers/postController.go b/controllers/postController.go index f0af29d..1674825 100644 --- a/controllers/postController.go +++ b/controllers/postController.go @@ -4,8 +4,10 @@ import ( "GoWeb/app" "GoWeb/models" "GoWeb/security" + "io/ioutil" "log" "net/http" + "os" "time" ) @@ -69,3 +71,46 @@ func (postController *PostController) Register(w http.ResponseWriter, r *http.Re http.Redirect(w, r, "/login", http.StatusFound) } + +func (postController *PostController) FileUpload(w http.ResponseWriter, r *http.Request) { + + max := postController.App.Config.Upload.MaxSize + r.ParseMultipartForm(max) + + // FormFile returns the first file for the given key `file` + // it also returns the FileHeader so we can get the Filename, + // the Header and the size of the file + file, handler, err := r.FormFile("file") + if err != nil { + log.Println("Error Retrieving the File") + log.Println(err) + return + } + defer file.Close() + + if handler.Size > max { + log.Println("User tried uploading a file which is too large.") + http.Redirect(w, r, "/", http.StatusRequestHeaderFieldsTooLarge) + return + } + + // Create a temporary file within upload directory + tempFile, err := os.Create(postController.App.Config.Upload.BaseName + handler.Filename) + if err != nil { + log.Println(err) + http.Redirect(w, r, "/", http.StatusNotAcceptable) + } + defer tempFile.Close() + + // read all of the contents of our uploaded file into a + // byte array + fileBytes, err := ioutil.ReadAll(file) + if err != nil { + log.Println(err) + } + // write this byte array to our temporary file + tempFile.Write(fileBytes) + // return that we have successfully uploaded our file! + + http.Redirect(w, r, "/", http.StatusFound) +} diff --git a/env_example.json b/env_example.json index 0708fdc..847b81f 100644 --- a/env_example.json +++ b/env_example.json @@ -13,5 +13,9 @@ }, "Template": { "BaseTemplateName": "templates/base.html" + }, + "Upload": { + "UploadDirectoryName": "goweb-uploads/", + "MaxUploadSize": 10485760 } -} \ No newline at end of file +} diff --git a/main.go b/main.go index 42e8ec0..09c1d29 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "GoWeb/routes" "context" "embed" + "errors" "log" "net/http" "os" @@ -43,6 +44,14 @@ func main() { file, err := os.OpenFile("logs/"+time.Now().Format("2006-01-02")+".log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) log.SetOutput(file) + // Create upload directory if it doesn't exist + uploadPath := appLoaded.Config.Upload.BaseName + if _, err := os.Stat(uploadPath); errors.Is(err, os.ErrNotExist) { + if err := os.MkdirAll(uploadPath, os.ModePerm); err != nil { + log.Fatal(err) + } + } + // Connect to database and run migrations appLoaded.Db = database.ConnectDB(&appLoaded) if appLoaded.Config.Db.AutoMigrate { diff --git a/routes/getRoutes.go b/routes/getRoutes.go index f12596f..f18f34c 100644 --- a/routes/getRoutes.go +++ b/routes/getRoutes.go @@ -30,4 +30,7 @@ func GetRoutes(app *app.App) { http.HandleFunc("/login", getController.ShowLogin) http.HandleFunc("/register", getController.ShowRegister) http.HandleFunc("/logout", getController.Logout) + + // Files + http.HandleFunc("/uploads", getController.ShowFile) } diff --git a/routes/postRoutes.go b/routes/postRoutes.go index 58ab50e..642c0a6 100644 --- a/routes/postRoutes.go +++ b/routes/postRoutes.go @@ -16,4 +16,5 @@ func PostRoutes(app *app.App) { // User authentication http.HandleFunc("/register-handle", postController.Register) http.HandleFunc("/login-handle", postController.Login) + http.HandleFunc("/upload-handle", postController.FileUpload) } diff --git a/templates/pages/home.html b/templates/pages/home.html index 4236a8f..8385106 100644 --- a/templates/pages/home.html +++ b/templates/pages/home.html @@ -1,5 +1,25 @@ {{ define "pageTitle" }}Home{{ end }} +{{ define "file-upload" }} +
+ + +
+{{ end }} + {{ define "content" }} {{ .Test }} -{{ end }} \ No newline at end of file + + + + + + +{{ end }} + +{{ define "content" }} +{{ end }}