megrez/libs/request/request.go
2024-12-29 01:02:31 +08:00

282 lines
6.2 KiB
Go

package request
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"time"
)
// Client ==> 客户端实例
type Client struct {
Request *Request
Cookies []*http.Cookie
Result Result
}
// Request ==> 请求体
type Request struct {
Url string
Method string
Data io.Reader
ContentType string
Authorization string
UserAgent string
Header map[string]string
Timeout time.Duration
// The proxy type is determined by the URL scheme. "http",
// "https", and "socks5" are supported. If the scheme is empty,
//
// If Proxy is nil or nil *URL, no proxy is used.
ProxyUrl url.URL
Redirect bool
MaxRedirects int
}
// Result ==> 结果集
type Result struct {
Header http.Header
Location *url.URL
Body []byte
Status int
}
// NewRequest ==> 新建请求
func NewRequest() *Client {
return &Client{
Request: &Request{
Method: "GET",
UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
Header: make(map[string]string),
Redirect: false,
MaxRedirects: 10,
},
Result: Result{},
}
}
// Do ==> 执行请求
func (c *Client) Do() *Client {
//HTTP请求构造
request, _ := http.NewRequest(c.Request.Method, c.Request.Url, c.Request.Data)
request.Header.Set("Content-Type", c.Request.ContentType)
if c.Request.Authorization != "" {
request.Header.Set("Authorization", c.Request.Authorization)
}
if c.Request.UserAgent != "" {
request.Header.Set("User-Agent", c.Request.UserAgent)
}
if len(c.Cookies) != 0 {
for _, cookie := range c.Cookies {
request.AddCookie(cookie)
}
}
// 支持自定义Header
for k, v := range c.Request.Header {
request.Header.Set(k, v)
}
var client *http.Client
if c.Request.ProxyUrl == (url.URL{}) {
client = &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if !c.Request.Redirect {
return http.ErrUseLastResponse
}
if len(via) >= c.Request.MaxRedirects {
return http.ErrUseLastResponse
}
return nil
},
}
} else {
client = &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(&c.Request.ProxyUrl)},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if !c.Request.Redirect {
return http.ErrUseLastResponse
}
if len(via) >= c.Request.MaxRedirects {
return http.ErrUseLastResponse
}
return nil
},
}
}
if c.Request.Timeout != 0 {
client.Timeout = c.Request.Timeout
}
res, err := client.Do(request)
if err != nil {
// fmt.Println(err)
return c
}
if len(res.Cookies()) > 1 {
c.Cookies = append(c.Cookies, res.Cookies()...)
}
defer res.Body.Close()
c.Result.Status = res.StatusCode
c.Result.Body, _ = io.ReadAll(res.Body)
c.Result.Header = res.Header
return c
}
// Get ==> 定义请求方式
func (c *Client) Get() *Client {
c.Request.Method = "GET"
return c
}
// Post ==> 定义请求方式
func (c *Client) Post() *Client {
c.Request.Method = "POST"
return c
}
// Put ==> 定义请求方式
func (c *Client) Put() *Client {
c.Request.Method = "PUT"
return c
}
// Patch ==> 定义请求方式
func (c *Client) Patch() *Client {
c.Request.Method = "PATCH"
return c
}
// Delete ==> 定义请求方式
func (c *Client) Delete() *Client {
c.Request.Method = "DELETE"
return c
}
// SetUrl ==> 定义请求目标
func (c *Client) SetUrl(url ...any) *Client {
c.Request.Url = fmt.Sprintf(url[0].(string), url[1:]...)
return c
}
// SetMethod ==> 定义请求方法
func (c *Client) SetMethod(method string) *Client {
c.Request.Method = method
return c
}
// SetContentType ==> 定义内容类型
func (c *Client) SetContentType(contentType string) *Client {
c.Request.ContentType = contentType
return c
}
// SetUserAgent ==> 定义用户代理
func (c *Client) SetUserAgent(userAgent string) *Client {
c.Request.UserAgent = userAgent
return c
}
// SetBody ==> 定义请求内容
func (c *Client) SetBody(body io.Reader) *Client {
c.Request.Data = body
return c
}
// SerHeaders ==> 定义请求头列表
func (c *Client) SetHeaders(headers map[string]string) *Client {
c.Request.Header = headers
return c
}
// SetHeader ==> 定义请求头
func (c *Client) SetHeader(key, value string) *Client {
c.Request.Header[key] = value
return c
}
// SetAuthorization ==> 定义身份验证
func (c *Client) SetAuthorization(credentials string) *Client {
c.Request.Authorization = credentials
return c
}
// SetTimeOut ==> 设置会话超时上限
func (c *Client) SetTimeout(timeout time.Duration) *Client {
c.Request.Timeout = timeout
return c
}
// SetCookie ==> 设置Cookie
func (c *Client) SetCookie(cookie *http.Cookie) *Client {
c.Cookies = append(c.Cookies, cookie)
return c
}
// SetCookies ==> 设置Cookies
func (c *Client) SetCookies(cookies string) *Client {
cookielist := strings.Split(cookies, "; ")
for _, cookie := range cookielist {
cookiekv := strings.Split(cookie, "=")
c.SetCookie(&http.Cookie{
Name: cookiekv[0],
Value: strings.Join(cookiekv[1:], "="),
})
}
return c
}
// SetProxy ==> 设置代理
func (c *Client) SetProxy(proxyUrl url.URL) *Client {
c.Request.ProxyUrl = proxyUrl
return c
}
// SetRedirect ==> 设置重定向
func (c *Client) SetRedirect(redirect bool) *Client {
c.Request.Redirect = redirect
return c
}
// SetMaxRedirects ==> 设置最大重定向次数
func (c *Client) SetMaxRedirects(maxRedirects int) *Client {
c.Request.MaxRedirects = maxRedirects
return c
}
// GetStatusCode ==> 获取请求状态码
func (c *Client) GetStatusCode() int {
return c.Result.Status
}
// GetBody ==> 获取返回内容
func (c *Client) GetBody() []byte {
return c.Result.Body
}
// GetBody ==> 获取返回内容
func (c *Client) GetBodyString() string {
return string(c.Result.Body)
}
// GetHeaders ==> 获取返回头字典
func (c *Client) GetHeaders() http.Header {
return c.Result.Header
}
// GetHeader ==> 获取返回头
func (c *Client) GetHeader(key string) string {
return c.Result.Header.Get(key)
}
// SaveToFile ==> 写出结果到文件
func (c *Client) SaveToFile(filepath string) (err error) {
// Write the body to file
err = os.WriteFile(filepath, c.GetBody(), 0777)
if err != nil {
return err
}
return nil
}