将文件从 url 发送到 cloudflare 图像失败

Send a File from url to cloudflare images fails

我正在使用 Google App Engine,这意味着只能通过云存储写入文件。当 API 被点击时,我可以毫无问题地抓取文件并将其存储在 google 云存储中。该函数只是 returns 它保存的 URL 。 我想获取该图像 URL,然后将其发送到 Cloudflare images,因为它们可以让您创建变体。

type ImageResult struct {
            Result struct {
                ID                string    `json:"id"`
                Filename          string    `json:"filename"`
                Uploaded          time.Time `json:"uploaded"`
                RequireSignedURLs bool      `json:"requireSignedURLs"`
                Variants          []string  `json:"variants"`
            } `json:"result"`
            ResultInfo interface{}   `json:"result_info"`
            Success    bool          `json:"success"`
            Errors     []interface{} `json:"errors"`
            Messages   []interface{} `json:"messages"`
}

以上是表示 Cloudflare 响应的结构。下面是直接获取 google 云存储 URL 并在将其发送到 Cloudflare 之前“下载”它的函数。

func CloudFlareURL(url, filename string) (*ImageResult, error) {
    cloudFlareUrl := "https://api.cloudflare.com/client/v4/accounts/" + konsts.CloudFlareAcc + "/images/v1"
    cloudFlareAuth := "Bearer " + konsts.CloudFlareApi
    r, err := http.Get(url)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't get the file")
    }
    if r.StatusCode != 200 {
        return nil, errors.New("Couldn't get the file")
    }
    defer r.Body.Close()
    buff := make([]byte, 4096)
    _, err = r.Body.Read(buff)

    req, err := http.NewRequest("POST", cloudFlareUrl, bytes.NewReader(buff))
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't create the request")
    }
    req.Header.Set("Content-Type", "multipart/form-data")
    req.Header.Set("Authorization", cloudFlareAuth)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't send the request")
    }

    var result ImageResult
    bodi := &bytes.Buffer{}
    _, err = bodi.ReadFrom(resp.Body)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't read the response body")
    }
    resp.Body.Close()
    err = json.Unmarshal(bodi.Bytes(), &result)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't unmarshal the response body")
    }
    return &result, nil
}

这是错误信息; 无效字符 'E' 正在寻找值的开头 无法解组响应正文

现在,如果我是 运行 api 服务器,在我的笔记本电脑上发送文件后,我可以将其保存在磁盘上,打开它并毫无问题地发送到 cloudflare。这是

的代码
func CloudFlareFile(params map[string]string, paramName, path string) (*ImageResult, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, err := writer.CreateFormFile(paramName, filepath.Base(path))
    if err != nil {
        return nil, err
    }
    _, err = io.Copy(part, file)

    for key, val := range params {
        _ = writer.WriteField(key, val)
    }
    err = writer.Close()
    if err != nil {
        return nil, err
    }
    cloudFlareUrl := "https://api.cloudflare.com/client/v4/accounts/" + konsts.CloudFlareAcc + "/images/v1"
    cloudFlareAuth := "Bearer " + konsts.CloudFlareApi
    req, err := http.NewRequest("POST", cloudFlareUrl, body)
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("Authorization", cloudFlareAuth)
    var result ImageResult
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't send the request")
    } else {
        body := &bytes.Buffer{}
        _, err := body.ReadFrom(resp.Body)
        if err != nil {
            return nil, errors.Wrap(err, "Couldn't read the response body")
        }
        resp.Body.Close()
        err = json.Unmarshal(body.Bytes(), &result)
        if err != nil {
            return nil, errors.Wrap(err, "Couldn't unmarshal the response body")
        }
    }
    return &result, nil
}
 

我试过各种变体,但总是失败。例如;

req, err := http.NewRequest("POST", cloudFlareUrl, r.body)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't create the request")
    }
    req.Header.Set("Content-Type", "multipart/form-data")
    req.Header.Set("Authorization", cloudFlareAuth)

好的,其他遇到此问题的人。我解决了。

r, err := http.Get(url)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't get the file")
    }
    if r.StatusCode != 200 {
        return nil, errors.New("Couldn't get the file")
    }
    defer r.Body.Close()
    b := &bytes.Buffer{}
    a := make([]byte, 4096)
    wr := multipart.NewWriter(b)
    part, err := wr.CreateFormFile("file", filename)
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't create the form file")
    }
    _, err = io.CopyBuffer(part, r.Body, a)
    wr.Close()

    req, err := http.NewRequest("POST", cloudFlareUrl, bytes.NewReader(b.Bytes()))
    if err != nil {
        return nil, errors.Wrap(err, "Couldn't create the request")
    }
    // req.Header.Set("Content-Type", "multipart/form-data")
    req.Header.Set("Content-Type", wr.FormDataContentType())
    req.Header.Set("Authorization", cloudFlareAuth)