Skip to content

Instantly share code, notes, and snippets.

@johanbrandhorst
Last active December 14, 2022 23:16
Show Gist options
  • Save johanbrandhorst/f08fca7945f2b0239e91c6cc99de109f to your computer and use it in GitHub Desktop.
Save johanbrandhorst/f08fca7945f2b0239e91c6cc99de109f to your computer and use it in GitHub Desktop.
Multipart form uploads in Go
package upload
func Upload(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
// Write straight to disk
err := req.ParseMultipartForm(0)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// We always want to remove the multipart file as we're copying
// the contents to another file anyway
defer func() {
if remErr := req.MultipartForm.RemoveAll(); remErr != nil {
// Log error?
}
}()
// Get any form metadata you may want
myVar := req.FormValue("my_variable")
// Start reading multi-part file under id "fileupload"
f, fh, err := req.FormFile("fileupload")
if err != nil {
if err == http.ErrMissingFile {
http.Error(w, "Request did not contain a file", http.StatusBadRequest)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
defer f.Close()
destDir, err := ioutil.TempDir("", "")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Remove destDir in case of error
defer func() {
if err != nil {
if remErr := os.RemoveAll(destDir); remErr != nil {
// Log some kind of warning probably?
}
}
}()
// Create a file in our temporary directory with the same name
// as the uploaded file
destFile, err := os.Create(path.Join(destDir, fh.Filename))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer destFile.Close()
// Write contents of uploaded file to destFile
if _, err = io.Copy(destFile, f); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment