resty

Resty 是一个快速、简单且强大的 Go 语言 HTTP 和 REST 客户端库,用于简化 HTTP 请求和响应处理。它功能丰富,性能优异,非常适合构建与 REST API 的交互逻辑。

常用方法

安装

1
go get github.com/go-resty/resty/v2

请求

请求配置

新建 client

1
2
3
4
5
6
7
8
9
10
11
12
client := resty.New()

// 配置代理
client.SetProxy("http://your-proxy-server.com:8080")
// 配置超时
client.SetTimeout(5 * time.Second)
// 设置重试次数
client.SetRetryCount(3)
// 设置重试等待时间
client.SetRetryWaitTime(2 * time.Second)
// 设置最大重试等待时间
client.SetRetryMaxWaitTime(10 * time.Second)

创建请求

1
req := client.R()

可以为请求设置需要的参数

配置 Content-Type

1
req.SetHeader("Content-Type", "application/x-www-form-urlencoded")

配置 Cookie

1
2
3
4
5
6
7
8
9
10
11
req.SetHeader("Cookie", "cookie")

// 配置指定 Cookie 字段
req.SetCookie(&http.Cookie{Name: "session", Value: "abc123"})

// 配置多个 Cookie 字段
cookies := []*http.Cookie{
{Name: "PHPSESSID", Value: "session"},
{Name: "security", Value: "low"},
}
req.SetCookies(cookies)

配置参数

1
2
3
4
5
6
req.SetQueryParams(map[string]string{
"id": "1",
"Submit": "Submit",
})

req.SetQueryString("id=1&Submit=Submit")

配置表单

1
2
3
4
req.SetFormData(map[string]string{
"username": "admin",
"password": "123456",
})

配置 Body

1
req.SetBody(`{"title": "foo", "body": "bar", "userId": 1}`)

保存响应至文件

1
req.SetOutput("response.json")

设置上传文件

1
req.SetFile("file", "path/to/your/file.txt")

开启调试功能查看发送的数据包和生成 Curl 命令功能

1
2
req.SetDebug(true)
req.EnableGenerateCurlOnDebug() // 可以使用 curlCmdExecuted := resp.Request.GenerateCurlCommand() 获取

解析响应体为结构体

1
2
3
4
5
6
7
8
type Post struct {
UserID int `json:"userId"`
ID int `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
}
var post Post
req.SetResult(&post)

发送数据包

1
2
// Post、Get、Head、Put、Delete、Options
resp, err := req.Post("http://localhost")

响应

1
2
3
4
fmt.Println(resp.StatusCode()) // 200
fmt.Println(resp.Status()) // 200 OK
fmt.Println(resp.Header()) // map[Accept-Ranges:[bytes] Cache-Control:[no-cache] Connection:[keep-alive]
fmt.Println(resp.String()) // body

中间件

Resty 的中间件(Middleware)是一种机制,用于在请求发送前或响应返回后,插入自定义的逻辑来处理 HTTP 请求或响应。这种机制可以用于日志记录、认证、缓存、重试、性能监控等场景。

请求中间件 OnBeforeRequest

1
2
3
4
5
6
client := resty.New()
client.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error {
c.SetProxy("http://127.0.0.1:7890") // 配置代理
r.SetHeader("Authorization", "Bearer YOUR_TOKEN") // 配置认证
return nil
})

响应中间件 OnAfterResponse

1
2
3
4
5
client := resty.New()
client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
fmt.Printf("Response received: %s\n", r.String())
return nil
})

案例

调用 Dify 任务,传入一个设定的 JSON,并解析响应返回对应 outputs 字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import (
"fmt"

"github.com/go-resty/resty/v2"
)

type DifyData struct {
Status string `json:"status"`
Outputs map[string]string `json:"outputs"`
}

type DifyRes struct {
DifyData DifyData `json:"data"`
}

func main() {
u := "http://127.0.0.1"
apiKey := "xxx"
j := `{"vul_desc": "xxx"}`
inputJson := fmt.Sprintf(`{"inputs": %s, "response_mode": "blocking", "user": "xxx"}`, j)
client := resty.New()
req := client.R()
var resJson DifyRes
req.SetResult(&resJson)
req.SetBody(inputJson)
req.SetAuthToken(apiKey)
req.SetHeader("Content-Type", "application/json")
resp, err := req.Post(u)
if err != nil {
fmt.Println(err)
}
if resp.StatusCode() == 200 && resJson.DifyData.Status == "succeeded" {
fmt.Println(resJson.DifyData.Outputs)
} else {
fmt.Println("failed")
}

}