How to Receive multipart from the client?

Here my code and output:

func RestClient(req *http.Request) {
		fmt.Println("main (120):::", req.MultipartForm.File)
}

main (120)::: &{map[userName:[0xc4200a66e0] diamond:[0xc4200f67b0] ]}

for k,v := range req.MultipartForm.File{
		if k == "userName" {
			for _, v2 := range v {
				fmt.Println("main (130):::",v2)
			}
		}
	}

main (130)::: &{ map[Content-Length:[8] Content-Disposition:[form-data; name=“dk”] Content-Transfer-Encoding:[binary] Content-Type:[multipart/form-data; charset=utf-8]] 8 [117 115 101 114 78 97 109 101] }

I want the (slice byte [117 115 101 114 78 97 109 101]) but can’t pull out that, how can print the (content byte), As we know the field from FileHeader struct:

type FileHeader struct {
	Filename string
	Header   textproto.MIMEHeader
	Size     int64

	content []byte
	tmpfile string
}

Thanks in advance.

When you are in the package that “owns” the FileHeader, you can use dot-notation to access the field, e.g. fh.content, if you are not the owner of that struct you can not access the field and have to take a look at the documentation of the owning package if there are functions or methods to extract the fields value.

PS: If you are talking about multipart.FileHeader, I can’t see a possibility to access that field on a quick glance, I didn’t delve the code though, perhaps its possible by "Open()ing it?

1 Like

Okay, I took a look at Open()s code:

https://golang.org/src/mime/multipart/formdata.go?s=3582:3791#L140

func (fh *FileHeader) Open() (File, error) {
	if b := fh.content; b != nil {
		r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
		return sectionReadCloser{r}, nil
	}
	return os.Open(fh.tmpfile)
}

So as you can see, if there is a non nil content, you can read it from the returned File after Open()ing the FileHeader, you can’t know from your code though, if there was something in FileHeader.content or if you get a file from disk, as this information is abstracted away.

Remember: identifiers starting with lowercase letters are not exported from a package and therefore can’t be used from the “outside”

2 Likes

thanks, you for help.
finally, I solved this problem:

for k,v := range req.MultipartForm.File{
		if k == "userName" {
			for _, v2 := range v {
				fmt.Println("main (130):::",v2)
	               b,_:=v2.Open()
					 sliceByte,_:=ioutil.ReadAll(b)
					   fmt.Println("main (245):::",string(sliceByte))
			}
		}
	}