mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
improve raw request/response content dump for ghttp.Client
This commit is contained in:
@ -19,13 +19,13 @@ import (
|
||||
|
||||
// dumpTextFormat is the format of the dumped raw string
|
||||
const dumpTextFormat = `+---------------------------------------------+
|
||||
| ghttp %s |
|
||||
| %s |
|
||||
+---------------------------------------------+
|
||||
%s
|
||||
%s
|
||||
`
|
||||
|
||||
// ifDumpBody determine whether to output body according to content-type
|
||||
// ifDumpBody determines whether to output body according to content-type.
|
||||
func ifDumpBody(contentType string) bool {
|
||||
// the body should not be output when the body is html or stream.
|
||||
if gstr.Contains(contentType, "application/json") ||
|
||||
@ -66,43 +66,34 @@ func getResponseBody(resp *http.Response) string {
|
||||
if errReadBody != nil {
|
||||
return ""
|
||||
}
|
||||
// so that the response body can be read again.
|
||||
// So the response body can be read again.
|
||||
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bytesBody))
|
||||
return gconv.UnsafeBytesToStr(bytesBody)
|
||||
}
|
||||
|
||||
// getRequest returns the request related to the response.
|
||||
// will return the copy of request when the request failed.
|
||||
func (r *ClientResponse) getRequest() *http.Request {
|
||||
if r.Response != nil && r.Request != nil {
|
||||
return r.Request
|
||||
}
|
||||
// r.req is the copy of request when the http request failed.
|
||||
if r.req != nil {
|
||||
return r.req
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RawRequest returns the raw text of the request.
|
||||
// RawRequest returns the raw content of the request.
|
||||
func (r *ClientResponse) RawRequest() string {
|
||||
// ClientResponse can be nil.
|
||||
if r == nil {
|
||||
return ""
|
||||
}
|
||||
req := r.getRequest()
|
||||
if req == nil {
|
||||
if r.request == nil {
|
||||
return ""
|
||||
}
|
||||
// DumpRequestOut writes more request headers than DumpRequest, such as User-Agent.
|
||||
bs, err := httputil.DumpRequestOut(req, false)
|
||||
bs, err := httputil.DumpRequestOut(r.request, false)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(dumpTextFormat, "REQUEST ", gconv.UnsafeBytesToStr(bs), getRequestBody(req))
|
||||
return fmt.Sprintf(
|
||||
dumpTextFormat,
|
||||
"REQUEST ",
|
||||
gconv.UnsafeBytesToStr(bs),
|
||||
getRequestBody(r.request),
|
||||
)
|
||||
}
|
||||
|
||||
// RawResponse returns the raw text of the response.
|
||||
// RawResponse returns the raw content of the response.
|
||||
func (r *ClientResponse) RawResponse() string {
|
||||
// ClientResponse can be nil.
|
||||
if r == nil || r.Response == nil {
|
||||
@ -113,7 +104,12 @@ func (r *ClientResponse) RawResponse() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf(dumpTextFormat, "RESPONSE", gconv.UnsafeBytesToStr(bs), getResponseBody(r.Response))
|
||||
return fmt.Sprintf(
|
||||
dumpTextFormat,
|
||||
"RESPONSE",
|
||||
gconv.UnsafeBytesToStr(bs),
|
||||
getResponseBody(r.Response),
|
||||
)
|
||||
}
|
||||
|
||||
// Raw returns the raw text of the request and the response.
|
||||
|
||||
@ -215,30 +215,28 @@ func (c *Client) DoRequest(method, url string, data ...interface{}) (resp *Clien
|
||||
if len(c.authUser) > 0 {
|
||||
req.SetBasicAuth(c.authUser, c.authPass)
|
||||
}
|
||||
// Sending request.
|
||||
var r *http.Response
|
||||
// do not return nil even if the request fails
|
||||
resp = &ClientResponse{}
|
||||
for {
|
||||
if r, err = c.Do(req); err != nil {
|
||||
if resp.Response, err = c.Do(req); err != nil {
|
||||
if c.retryCount > 0 {
|
||||
c.retryCount--
|
||||
time.Sleep(c.retryInterval)
|
||||
} else {
|
||||
// we need a copy of the request when the request fails.
|
||||
resp.req = req
|
||||
resp.request = req
|
||||
return resp, err
|
||||
}
|
||||
} else {
|
||||
resp.request = resp.Request
|
||||
break
|
||||
}
|
||||
}
|
||||
resp.Response = r
|
||||
|
||||
// Auto saving cookie content.
|
||||
if c.browserMode {
|
||||
now := time.Now()
|
||||
for _, v := range r.Cookies() {
|
||||
for _, v := range resp.Response.Cookies() {
|
||||
if v.Expires.UnixNano() < now.UnixNano() {
|
||||
delete(c.cookies, v.Name)
|
||||
} else {
|
||||
|
||||
@ -9,15 +9,14 @@ package ghttp
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
// ClientResponse is the struct for client request response.
|
||||
type ClientResponse struct {
|
||||
req *http.Request // just a copy of the request when the request failed.
|
||||
*http.Response
|
||||
request *http.Request
|
||||
cookies map[string]string
|
||||
}
|
||||
|
||||
@ -49,7 +48,7 @@ func (r *ClientResponse) GetCookieMap() map[string]string {
|
||||
|
||||
// ReadAll retrieves and returns the response content as []byte.
|
||||
func (r *ClientResponse) ReadAll() []byte {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
body, err := ioutil.ReadAll(r.Response.Body)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -64,5 +63,5 @@ func (r *ClientResponse) ReadAllString() string {
|
||||
// Close closes the response when it will never be used.
|
||||
func (r *ClientResponse) Close() error {
|
||||
r.Response.Close = true
|
||||
return r.Body.Close()
|
||||
return r.Response.Body.Close()
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ func Test_BindMiddleware_Basic1(t *testing.T) {
|
||||
r.Response.Write("8")
|
||||
})
|
||||
s.SetPort(p)
|
||||
//s.SetDumpRouterMap(false)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
@ -248,7 +248,7 @@ func Test_Middleware_Hook_With_Static(t *testing.T) {
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
//s.SetDumpRouterMap(false)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.SetServerRoot(gdebug.TestDataPath("static1"))
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
@ -701,7 +701,7 @@ func Test_Middleware_Panic(t *testing.T) {
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
//s.SetDumpRouterMap(false)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
@ -349,7 +349,7 @@ func Test_Router_DomainGroup(t *testing.T) {
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
//s.SetDumpRouterMap(false)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ func Test_Router_Hook_Fuzzy_Router(t *testing.T) {
|
||||
r.Response.Write(r.Router.Uri)
|
||||
})
|
||||
s.SetPort(p)
|
||||
//s.SetDumpRouterMap(false)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user