Last active
December 14, 2022 23:16
-
-
Save johanbrandhorst/f08fca7945f2b0239e91c6cc99de109f to your computer and use it in GitHub Desktop.
Multipart form uploads in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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