2023-08-06 01:17:27 +08:00
|
|
|
package curlx
|
|
|
|
|
|
|
|
|
|
import (
|
2025-12-28 15:14:05 +08:00
|
|
|
"compress/gzip"
|
|
|
|
|
"io"
|
2023-08-06 01:17:27 +08:00
|
|
|
"net"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/tidwall/gjson"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Response response object
|
|
|
|
|
type Response struct {
|
2025-12-28 15:14:05 +08:00
|
|
|
Response *http.Response
|
|
|
|
|
Request *http.Request
|
|
|
|
|
Body []byte
|
|
|
|
|
Err error
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
func (l *Response) Close() error {
|
|
|
|
|
if l.Response.Body != nil {
|
|
|
|
|
return l.Response.Body.Close()
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
2025-12-28 15:14:05 +08:00
|
|
|
return nil
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetRequest get request object
|
|
|
|
|
func (r *Response) GetRequest() *http.Request {
|
2025-12-28 15:14:05 +08:00
|
|
|
return r.Request
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
func (r *Response) GetResponse() *http.Response {
|
|
|
|
|
return r.Response
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
// GetBody parse response body
|
|
|
|
|
func (r *Response) GetBody() ([]byte, error) {
|
|
|
|
|
if r.Err != nil {
|
|
|
|
|
return nil, r.Err
|
|
|
|
|
}
|
|
|
|
|
if r.Body != nil {
|
|
|
|
|
return r.Body, nil
|
|
|
|
|
}
|
|
|
|
|
if r.Response == nil {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
body := []byte{}
|
|
|
|
|
var err error
|
|
|
|
|
if r.Response.Header.Get("Content-Encoding") == "gzip" {
|
|
|
|
|
reader, err := gzip.NewReader(r.Response.Body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer reader.Close()
|
|
|
|
|
body, err = io.ReadAll(reader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
body, err = io.ReadAll(r.Response.Body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// close body
|
|
|
|
|
r.Response.Body.Close()
|
2023-08-06 01:17:27 +08:00
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
r.Body = body
|
|
|
|
|
return body, err
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
func (r Response) GetStatusCode() int {
|
|
|
|
|
if r.Response == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
return r.Response.StatusCode
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsTimeout get if request is timeout
|
|
|
|
|
func (r *Response) IsTimeout() bool {
|
2025-12-28 15:14:05 +08:00
|
|
|
if r.Err == nil {
|
2023-08-06 01:17:27 +08:00
|
|
|
return false
|
|
|
|
|
}
|
2025-12-28 15:14:05 +08:00
|
|
|
netErr, ok := r.Err.(net.Error)
|
2023-08-06 01:17:27 +08:00
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if netErr.Timeout() {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-28 15:14:05 +08:00
|
|
|
// GetParsedBody parse response body with gjson
|
|
|
|
|
func (r *Response) GetParsedBody() (*gjson.Result, error) {
|
|
|
|
|
body, err := r.GetBody()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
pb := gjson.ParseBytes(body)
|
|
|
|
|
|
|
|
|
|
return &pb, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-06 01:17:27 +08:00
|
|
|
// GetHeaders get response headers
|
|
|
|
|
func (r *Response) GetHeaders() map[string][]string {
|
2025-12-28 15:14:05 +08:00
|
|
|
return r.Response.Header
|
2023-08-06 01:17:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetHeader get response header
|
|
|
|
|
func (r *Response) GetHeader(name string) []string {
|
|
|
|
|
headers := r.GetHeaders()
|
|
|
|
|
for k, v := range headers {
|
2025-09-13 22:23:29 +08:00
|
|
|
if strings.EqualFold(name, k) {
|
2023-08-06 01:17:27 +08:00
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetHeaderLine get a single response header
|
|
|
|
|
func (r *Response) GetHeaderLine(name string) string {
|
|
|
|
|
header := r.GetHeader(name)
|
|
|
|
|
if len(header) > 0 {
|
|
|
|
|
return header[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HasHeader get if header exsits in response headers
|
|
|
|
|
func (r *Response) HasHeader(name string) bool {
|
|
|
|
|
headers := r.GetHeaders()
|
|
|
|
|
for k := range headers {
|
2025-09-13 17:50:06 +08:00
|
|
|
if strings.EqualFold(name, k) {
|
2023-08-06 01:17:27 +08:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|