Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set Content-Type for a form filed using 'multipart' in Go

I am attempting to upload a file that requires me to set a specific Content-Type for the API. When I do this:

file, err := os.Open("helloWorld.wav")
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
audioFile, _ := writer.CreateFormFile("file", "helloWorld.wav")
_, err = io.Copy(audioFile, file)
if err != nil {
     return nil, 0, err
}
writer.Close()

It creates the multipart form properly, but assumes this content type:

Content-Type: application/octet-stream

I need to be able to set it to:

Content-Type: audio/wav;rate=8000

While of course I may set the headers for net/http, I am not seeing how to do this for individual fields in a multipart form.

like image 731
jsgoecke Avatar asked Jan 15 '14 06:01

jsgoecke


People also ask

How do you set content type as multipart form data?

For the most part, the main difference is the Content-Type of the different form fields or “Parameters”. The first form part should be “application/json” and the binary file type should be “application/pdf”.

What is the content type of multipart file?

The multipart/byteranges content type is defined as a part of the HTTP message protocol. It includes two or more parts, each with its own Content-Type and Content-Range fields. The parts are separated using a MIME boundary parameter.

How do you use multipart form data?

Multipart form data: The ENCTYPE attribute of <form> tag specifies the method of encoding for the form data. It is one of the two ways of encoding the HTML form. It is specifically used when file uploading is required in HTML form. It sends the form data to server in multiple parts because of large size of file.

What is multipart form data format?

multipart/form-data" contains a series of parts. Each part is expected to contain a content-disposition header [RFC 2183] where the disposition type is "form-data", and where the disposition contains an (additional) parameter of "name", where the value of that parameter is the original field name in the form.


1 Answers

Looking at the source code mime/multipart it's not possible, but you could implement something like this (note: it's not handling the escaping of filename correctly)

    func CreateAudioFormFile(w *multipart.Writer, filename string) (io.Writer, error) {
      h := make(textproto.MIMEHeader)
      h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, "file", filename))
      h.Set("Content-Type", "audio/wav;rate=8000")
      return w.CreatePart(h)
}

Outputs

--0c4c6b408a5a8bf7a37060e54f4febd6083fd6758fd4b3975c4e2ea93732 Content-Disposition: form-data; name="file"; filename="helloWorld.wav" Content-Type: audio/wav;rate=8000 --0c4c6b408a5a8bf7a37060e54f4febd6083fd6758fd4b3975c4e2ea93732--

See playground for full example.

Edit: To write the file data, also copy it to the writer as in the original example.

audioFile, _ := CreateAudioFormFile(writer2, "helloWorld.wav")
io.Copy(audioFile, file)

See updated playground for the full example that includes the file data.

like image 147
Stuart McConnell Avatar answered Oct 09 '22 15:10

Stuart McConnell