http - 在 Golang 中转换 curl 请求并将文件作为有效负载的一部分发送

标签 http go curl request http-post

我有一个看起来像这样的 curl 请求

curl -X POST https://kon-stage-ew1.pet.io/predict/pet-find/v1/predict \
  -H 'x-kon-Predict-Backend: https://kon-94fkr5wXRCeNu3IiDXzXFg-stage.cloud.pet.io' \
  -H 'x-analyzer-id: Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016' \
  -H 'x-api-key: redStagekey' \
  -F 'properties={}' \
  -F content=@/Users/peter/Documents/01.jpg

这个 curl 请求的 python http 看起来像这样
image1 = '01.jpg'
    headers = {
        'x-kon-Predict-Backend': 'https://kon-94fkr5wXRCeNu3IiDXzXFg-stage.cloud.pet.io',
        'x-analyzer-id': 'Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016',
        'x-api-key': 'redStagekey',
    }

    payload = {'properties':'{}'}

    files = {
        'content':open(image1, 'rb')
    }

    response = requests.post('https://kon-stage-ew1.pet.io/predict/pet-find/v1/predict', headers=headers, data = payload, files=files)
    return response.content

我想将其转换为等效的 Golang http 请求。
我尝试了几个 Golang 库,如 grequests、http 以及此处的博客文章 https://matt.aimonetti.net/posts/2013-07-golang-multipart-file-upload-example/
但它们似乎都不起作用。
这是我尝试过的示例 grequest
package main

import (
    "github.com/levigross/grequests"
    "fmt"
)

func main(){

    url := "https://kon-stage-ew1.pet.io/predict/exposure-defect/v1/predict"

    headers := map[string]string{
        "x-kon-Predict-Backend": "https://kon-94fkr5wXRCeNu3IiDXzXFg-stage-eu-west-1.stage.cloud.pet.io",
        "x-analyzer-id": "Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016",
        "x-api-key": "redStageKey",
    }

    payload := map[string]string{
        "properties":"{}",
    }

    file_upload, err := grequests.FileUploadFromDisk("/Users/akhikuma/Documents/01.jpg")

    if err != nil {
        fmt.Println("Unable to open file: ", err)
    }

    ro := &grequests.RequestOptions{
        Headers: headers,
        Files: file_upload,
        Data: payload,
    }
    resp, err := grequests.Post(url,ro)

    if err!=nil {
        fmt.Println("Something wrong happened in post request: ", err)
        fmt.Println(err)
    }

    fmt.Println(resp)
    if resp.Ok != true {
        fmt.Println("Request did not return OK")
    }

}

这给了我以下错误
{"status_code": 400, "reason": "('Content data is missing. Check multipart file upload.', 400)"}
Request did not return OK

我还尝试使用 postman 将 curl 请求转换为 golang,但它也无法正常工作,因为该请求包括上传文件。

请注意,在 python 代码中,我只是不发送文件,而是发送文件的字典。
我尝试使用 postman 将 curl 请求转换为 Golang,但它不起作用,因为我们还必须将文件作为有效负载的一部分发送。

谢谢你的帮助。

最佳答案

与go文件同一目录下的文件,试试这段代码。我遇到了
no such host error但我认为这会奏效。

package main

import (
    "bytes"
    "fmt"
    "io"
    "log"
    "mime/multipart"
    "net/http"
    "os"
    "path/filepath"
)

func main() {
    path, _ := os.Getwd()
    path += "/your/filename/here"

    url := "https://kon-stage-ew1.pet.io/predict/exposure-defect/v1/predict"

    file, err := os.Open(path)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

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

    err = writer.WriteField("properties", "{}")
    if err != nil {
        log.Fatal(err)
    }
    err = writer.Close()
    if err != nil {
        log.Fatal(err)
    }

    client := http.Client{}
    req, err := http.NewRequest("POST", url, body)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("x-kon-Predict-Backend", "https://kon-94fkr5wXRCeNu3IiDXzXFg-stage-eu-west-1.stage.cloud.pet.io")
    req.Header.Set("x-analyzer-id", "Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016")
    req.Header.Set("x-api-key", "redStageKey")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    } else {
        body := &bytes.Buffer{}
        _, err := body.ReadFrom(resp.Body)
        if err != nil {
            log.Fatal(err)
        }
        resp.Body.Close()
        fmt.Println(resp.StatusCode)
        fmt.Println(resp.Header)
        fmt.Println(body)
    }
}

关于http - 在 Golang 中转换 curl 请求并将文件作为有效负载的一部分发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61517698/

相关文章:

去 float 除法

php - PHP cURL访问失败至远程Docker Hub/注册表

curl - 如何通过 cURL 调用使用 HTTP 请求发送 header ?

java - 当我将 Retrofit2.0 与 POST 一起使用时, body 为 null ,但响应代码为 5xx?

go - 如何在golang中的指定路径上创建一个空文件。可以说$ HOME/newFile.txt

python - 我如何针对 python HTTPConnection 进行 read()/write() 操作?

java - 将 Java 应用程序移植到 Go - 有什么建议吗?

curl - 如何使用 CURLINFO_*_TIME 值估算 cURL 请求的代理连接时间?

http - 使用 uri 模块的 SPNEGO 身份验证

c# - 如何处理内容处置错误