代码拉取完成,页面将自动刷新
package rest
import (
"compress/flate"
"compress/gzip"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"gitee.com/hexug/go-chain-restful-client/common/format"
"gitee.com/hexug/go-chain-restful-client/negotiator"
"github.com/andybalholm/brotli"
"github.com/bytedance/sonic"
"github.com/golang/snappy"
"github.com/klauspost/compress/zstd"
)
func (r *Response) withBody(body io.ReadCloser) {
r.body = body
}
func (r *Response) withHeader(headers http.Header) {
r.headers = headers
}
func (r *Response) withStatusCode(code int) {
r.statusCode = code
}
func (r *Response) withStatus(status string) {
r.status = status
}
func (r *Response) withCookies(cookies []*http.Cookie) {
r.cookies = cookies
}
func (r *Response) withUrl(url *url.URL) {
r.url = url
}
func (r *Response) readBody() {
r.lock.Lock()
defer r.lock.Unlock()
if r.body == nil || r.isRead {
return
}
r.isRead = true
defer r.body.Close()
var bodyReader io.Reader
switch HeaderFilterFlags(r.headers.Get(CONTENT_ENCODING_HEADER)) {
case "gzip":
dp, err := gzip.NewReader(r.body)
if err != nil {
r.err = err
return
}
bodyReader = dp
case "deflate":
bodyReader = flate.NewReader(r.body)
case "br":
bodyReader = brotli.NewReader(r.body)
case "zstd":
dp, err := zstd.NewReader(r.body)
if err != nil {
r.err = err
return
}
bodyReader = dp
case "snappy":
bodyReader = snappy.NewReader(r.body)
default:
bodyReader = r.body
}
// 读取数据
body, err := io.ReadAll(bodyReader)
if err != nil {
r.err = err
return
}
r.debug(body)
r.bf = body
}
func (r *Response) debug(body []byte) {
r.log.L().Debugf("状态码: %d", r.statusCode)
r.log.L().Debugf("响应头:")
for k, v := range r.headers {
r.log.L().Debugf("\t%s=%s", k, strings.Join(v, ","))
}
var data interface{}
err := sonic.Unmarshal(body, &data)
if err == nil {
r.log.L().Debugln("Body: ", format.FormatBytesToJsion(body))
} else {
r.log.L().Debugln("Body: ", string(body))
}
}
// 链式获取header 通过传入一个header的key和接收的字符串指针,返回的对应value是在传入的字符串指针中
func (r *Response) Header(header string, v *string) *Response {
*v = r.headers.Get(header)
return r
}
// 不处理返回, 直接判断请求是否正常
func (r *Response) Error() error {
r.readBody()
// 判断status code
if r.statusCode/100 != 2 && r.statusCode/100 != 3 {
r.err = fmt.Errorf("状态码是:%d, 非2xx或者3XX\n响应数据:%s", r.statusCode, string(r.bf))
// r.log.L().Errorw("############################################")
// r.log.L().Errorf("状态码是:%d, not 2xx或者3XX", r.statusCode)
// r.log.L().Errorf("响应数据: %s", string(r.bf))
// r.log.L().Errorw("############################################")
}
return r.err
}
// 请求正常的情况下, 获取返回的数据, 不做解析,以byte[]形式返回
func (r *Response) Raw() ([]byte, error) {
if err := r.Error(); err != nil {
return nil, err
}
return r.bf, r.err
}
// TODO待改进
func (r *Response) Into(v any) error {
if err := r.Error(); err != nil {
return err
}
if r.contentType == "" {
r.contentType = HeaderFilterFlags(r.headers.Get(CONTENT_TYPE_HEADER))
}
nt := negotiator.GetNegotiator(r.contentType)
return nt.Decode(r.bf, v)
}
// 获取相应状态码
func (r *Response) StatusCode() int {
return r.statusCode
}
// 非链式获取header,直接返回header的key对应的value
func (r *Response) GetHeader(key string) string {
return r.headers.Get(key)
}
// 获取所有的header
func (r *Response) Headers() http.Header {
return r.headers
}
// 获取相应状态
func (r *Response) Status() string {
return r.status
}
// 获取响应的cookie
func (r *Response) Cookies() []*http.Cookie {
return r.cookies
}
// 获取响应的编码类型
func (r *Response) Encoding() string {
return r.GetHeader("Content-Type")
}
// 获取文本格式的body
func (r *Response) Text() string {
if err := r.Error(); err != nil {
r.log.L().Errorln("获取文本格式的body异常:", err.Error())
return ""
}
var data interface{}
err := sonic.Unmarshal(r.bf, &data)
if err == nil {
return format.FormatBytesToJsion(r.bf)
} else {
return string(r.bf)
}
}
// 获取URL
func (r *Response) Url() *url.URL {
return r.url
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。