Repository: claudiodangelis/qrcp
File: serveHTTP.go (Go)

Code before:
<form action="`+route+`" method="post" enctype="multipart/form-data">
  <label for="file">Filename:</label>
  <input type="file" name="files" id="files" multiple>
  <br>
  <input type="submit" name="submit" value="Submit">
</form>
</body>
</html>`)
		}
		if r.Method == "POST" {
			defer wg.Done()
			r.ParseMultipartForm(32 << 20) // 32MB is the default used by http.Request.FormFile()
			fileHeaders := r.MultipartForm.File["files"]
			for _, fileHeader := range fileHeaders {
				// open provided file
				file, err := fileHeader.Open()
				defer file.Close()
				if err != nil {
					fmt.Fprintf(w, "Unable to read provided file: %v\n", err) //output to server
					log.Printf("Unable to read provided file: %v\n", err) //output to console
					stop <- true // send signal to server to shutdown
				}

				// try to create output file
				out, err := os.Create(filepath.Join(dirToStore, fileHeader.Filename))
				defer out.Close()
				if err != nil {
					if os.IsNotExist(err) {
						err := os.MkdirAll(dirToStore, os.ModePerm)
						if err != nil {
							fmt.Fprintf(w, "Unable to create specifyed dir: %s\n", err) //output to server
							log.Printf("Unable to create specifyed dir: %v\n", err) //output to console
							stop <- true // send signal to server to shutdown
						}
						// create output file if error was handled succesfully
						out, _ = os.Create(filepath.Join(dirToStore, fileHeader.Filename))
					} else {
						fmt.Fprintf(w, "Unable to create the file for writing: %s\n", err) //output to server
						log.Printf("Unable to create the file for writing: %s\n", err) //output to console
						stop <- true // send signal to server to shutdown
					}
				}
				// create output file if error was handled succesfully
				out, _ = os.Create(filepath.Join(dirToStore, fileHeader.Filename))

				// write the content from POSTed file to the out
				_, err = io.Copy(out, file)
				if err != nil {
					fmt.Fprintf(w, "Unable to write file to disk: %v", err) //output to server
					log.Printf("Unable to write file to disk: %v", err) //output to console
					stop <- true // send signal to server to shutdown

Review comment (suggestion):
Move `defer out.Close()` _after_ checking the error

Code after:
<h2>Upload a file</h2>
<form action="`+route+`" method="post" enctype="multipart/form-data">
  <label for="file">Filename:</label>
  <input type="file" name="files" id="files" multiple>
  <br>
  <input type="submit" name="submit" value="Submit">
</form>
</body>
</html>`)
		}
		if r.Method == "POST" {
			defer wg.Done()

			// make sure dirToStore is exist
			filesInfo, err := ioutil.ReadDir(dirToStore)
			if err != nil && os.IsNotExist(err) {
				// if not exist try to create directories in path to dirToStore
				if err := os.MkdirAll(dirToStore, os.ModePerm); err != nil {
					fmt.Fprintf(w, "Unable to create specifyed dir: %s\n", err) //output to server
					log.Printf("Unable to create specifyed dir: %v\n", err)     //output to console
					stop <- true                                                // send signal to server to shutdown
					return
				}
			}

			// create array of names of files which are stored in dirToStore
			// used later to set valid name for received files
			fileNamesInTargetDir := make([]string, len(filesInfo))
			for _, fi := range filesInfo {
				fileNamesInTargetDir = append(fileNamesInTargetDir, fi.Name())
			}

			r.ParseMultipartForm(32 << 20) // 32MB is the default used by http.Request.FormFile()
			fileHeaders := r.MultipartForm.File["files"]
			for _, fileHeader := range fileHeaders {
				// open provided file
				file, err := fileHeader.Open()
				defer file.Close()
				if err != nil {
					fmt.Fprintf(w, "Unable to read provided file: %v\n", err) //output to server
					log.Printf("Unable to read provided file: %v\n", err)     //output to console
					stop <- true                                              // send signal to server to shutdown
					return
				}

				// seting name of new file
				// if name isn't taken leave it unchanged
				// else change name to format "name(number).ext"
				newFilename := fileHeader.Filename
				fileExt := filepath.Ext(newFilename)
				fileName := strings.TrimSuffix(newFilename, fileExt)