Reputation: 13
When uploading a file to my go app, I encounter a panic.
panic: runtime error: invalid memory address or nil pointer dereference
/Users/bob/Projects/go/src/github.com/zenazn/goji/web/middleware/recoverer.go:24 (0xbaf5b)
func.006: debug.PrintStack()
/usr/local/go/src/pkg/runtime/panic.c:248 (0x1043d)
panic: runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
/usr/local/go/src/pkg/runtime/panic.c:552 (0x10eed)
panicstring: runtime·panic(err);
/usr/local/go/src/pkg/runtime/os_darwin.c:454 (0xfb8e)
sigpanic: runtime·panicstring("invalid memory address or nil pointer dereference");
/usr/local/go/src/pkg/mime/multipart/multipart.go:223 (0xb6801)
(*Reader).NextPart: if r.currentPart != nil {
/Users/bob/Projects/go/src/github.com/app/controllers/company_sheet_controller.go:32 (0x2ee18)
NewCompanySheet: part, err := mr.NextPart()
/usr/local/go/src/pkg/net/http/server.go:1235 (0x44f00)
HandlerFunc.ServeHTTP: f(w, r)
/Users/bob/Projects/go/src/github.com/zenazn/goji/web/router.go:113 (0x6bc0a)
This method handles an upload from a multipart form, extracting the file contents and boundary data. The r.FormFile
method on request is used to set file and header. And in order to pull the additional data from the post, I use r.MultipartReader
. From the error description I see r
is already declared as ParseMultipartForm
when using r.FormFile
. When executing the function with the different request methods individually, I receive no errors. r.FormFile
and r.MultipartReader
work fine isolated. Am I unable to mix the two request methods?
func Upload(r *http.Request) {
file, header, err := r.FormFile("file")
ErrorCheck(err)
mr, err := r.MultipartReader()
ErrorCheck(err)
part, err := mr.NextPart()
ErrorCheck(err)
var b bytes.Buffer
io.CopyN(&b, part, int64(1<<20))
fmt.Println(b.String())
defer file.Close()
}
Upvotes: 1
Views: 4349
Reputation: 2100
You are calling FormFile() at the beginning of your function.
This calls ParseMultipartForm() (see Request.FormFile) which populates the MultipartForm field of your http.Request.
Now the documentation for MultipartReader() states that you should use MultipartReader() instead of ParseMultipartForm() if you want to process the data as stream.
Looking at the source MultipartReader() returns an error if the MultipartForm field was already set.
So to answer your question: No, you can't use both functions for the same request.
Also your
defer file.Close()
should be right after you checked for an error from FormFile(), otherwise the file won't be closed before Garbage Collection, when your function panics.
Upvotes: 2