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

huangapple go评论133阅读模式
英文:

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

问题

我正在尝试上传一个文件,需要为API设置特定的Content-Type。当我这样做时:

  1. file, err := os.Open("helloWorld.wav")
  2. buf := new(bytes.Buffer)
  3. writer := multipart.NewWriter(buf)
  4. audioFile, _ := writer.CreateFormFile("file", "helloWorld.wav")
  5. _, err = io.Copy(audioFile, file)
  6. if err != nil {
  7. return nil, 0, err
  8. }
  9. writer.Close()

它正确地创建了multipart表单,但是假设了这个内容类型:

  1. Content-Type: application/octet-stream

我需要能够将其设置为:

  1. Content-Type: audio/wav;rate=8000

当然,我可以为net/http设置头部,但是我不知道如何为multipart表单中的单个字段设置头部。

英文:

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

  1. file, err := os.Open("helloWorld.wav")
  2. buf := new(bytes.Buffer)
  3. writer := multipart.NewWriter(buf)
  4. audioFile, _ := writer.CreateFormFile("file", "helloWorld.wav")
  5. _, err = io.Copy(audioFile, file)
  6. if err != nil {
  7. return nil, 0, err
  8. }
  9. writer.Close()

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

  1. Content-Type: application/octet-stream

I need to be able to set it to:

  1. 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.

答案1

得分: 18

查看源代码mime/multipart,似乎不可能实现,但你可以实现类似的功能(注意:它没有正确处理文件名的转义)。

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

输出结果:

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

完整示例请参见playground

编辑:要写入文件数据,也将其复制到写入器中,就像原始示例中一样。

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

包含文件数据的完整示例请参见更新的playground

英文:

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)

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

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.

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

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

huangapple
  • 本文由 发表于 2014年1月15日 14:33:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/21130566.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定