Golang 向 http 多部分请求添加多个文件

Ant*_*ter 2 multipart go

目前我正在分别流式传输 2 个多部分请求。

  1. 包含作为 blob 的文件
  2. 包含一个 json 文件作为 blob 的描述

如何使用多部分同时上传它们?

这是运行 2 次的请求。我想在这 1 个请求中添加 2 个文件

 func(c *Client) Upload(h *UploadHandle) (*PutResult, error) {
        bodyReader, bodySize, err := h.Read()
        if err != nil {
            return nil, fmt.Errorf("Failed to peek the body size %v", err)
        }

        if bodySize > constants.MaxDropSize {
            return nil, errors.New("The size of the body is to big")
        }

        pipeReader, pipeWriter := io.Pipe()
        writer := multipart.NewWriter(pipeWriter)

        errChan := make(chan error, 1)
        go func() {
            defer pipeWriter.Close()
            part, err := writer.CreateFormFile(h.DropRef, h.DropRef)
            if err != nil {
                errChan <- err
                return
            }
            _, err = io.Copy(part, bodyReader)
            if err == nil {
                err = writer.Close()
            }
            errChan <- err
        }()

        uploadUrl := fmt.Sprintf("%s/drops/upload", c.Server)
        req, err := http.NewRequest("POST", uploadUrl, pipeReader)
        if err != nil {
            return nil, err
        }
        req.Header.Add("Content-Type", writer.FormDataContentType())
        req.Body = ioutil.NopCloser(pipeReader)

        resp, err := c.Do(req)
        if err != nil {
            return nil, fmt.Errorf("Failed doing request: %v", err)
        }
        defer resp.Body.Close()

        // Handling the error the routine may caused
        if err := <-errChan; err != nil {
            return nil, err
        }
        if resp.StatusCode != 200 {
            return nil, fmt.Errorf("The server responded with a status %d", resp.StatusCode)
        }
    return &PutResult{h.DropRef, bodySize}, nil
}
Run Code Online (Sandbox Code Playgroud)

One*_*One 5

您只需CreateFormFile再次调用(或CreateFormField) 并将您的 json 写入返回的编写器。

j, err := writer.CreateFormFile("meta", h.DropRef + ".json")
enc := json.NewEncoder(j)
enc.Encode(some-struct-you-want-to-write-as-json)
Run Code Online (Sandbox Code Playgroud)

只需确保在创建新文件之前完成第一个文件的编写,因为根据文档

调用 CreatePart 后,可能不再写入任何先前的部分。