2020-04-08 19:24:03 +08:00
|
|
|
// Copyright 2020 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
|
|
|
|
package ghttp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httputil"
|
|
|
|
|
|
|
|
"github.com/gogf/gf/text/gstr"
|
|
|
|
"github.com/gogf/gf/util/gconv"
|
|
|
|
)
|
|
|
|
|
2020-04-11 12:16:53 +08:00
|
|
|
// dumpTextFormat is the format of the dumped raw string
|
2020-04-08 19:24:03 +08:00
|
|
|
const dumpTextFormat = `+---------------------------------------------+
|
2020-04-24 00:00:52 +08:00
|
|
|
| %s |
|
2020-04-08 19:24:03 +08:00
|
|
|
+---------------------------------------------+
|
|
|
|
%s
|
|
|
|
%s
|
|
|
|
`
|
|
|
|
|
2020-04-24 00:00:52 +08:00
|
|
|
// ifDumpBody determines whether to output body according to content-type.
|
2020-04-08 19:24:03 +08:00
|
|
|
func ifDumpBody(contentType string) bool {
|
2020-04-11 12:16:53 +08:00
|
|
|
// the body should not be output when the body is html or stream.
|
2020-04-08 19:24:03 +08:00
|
|
|
if gstr.Contains(contentType, "application/json") ||
|
|
|
|
gstr.Contains(contentType, "application/xml") ||
|
|
|
|
gstr.Contains(contentType, "multipart/form-data") ||
|
|
|
|
gstr.Contains(contentType, "application/x-www-form-urlencoded") ||
|
|
|
|
gstr.Contains(contentType, "text/plain") {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-04-11 12:16:53 +08:00
|
|
|
// getRequestBody returns the raw text of the request body.
|
2020-04-08 19:24:03 +08:00
|
|
|
func getRequestBody(req *http.Request) string {
|
|
|
|
contentType := req.Header.Get("Content-Type")
|
|
|
|
if !ifDumpBody(contentType) {
|
|
|
|
return ""
|
|
|
|
}
|
2020-04-11 12:16:53 +08:00
|
|
|
// so that the request body can be read again.
|
2020-04-08 19:24:03 +08:00
|
|
|
bodyReader, errGetBody := req.GetBody()
|
|
|
|
if errGetBody != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
bytesBody, errReadBody := ioutil.ReadAll(bodyReader)
|
|
|
|
if errReadBody != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return gconv.UnsafeBytesToStr(bytesBody)
|
|
|
|
}
|
|
|
|
|
2020-04-11 12:16:53 +08:00
|
|
|
// getResponseBody returns the text of the response body.
|
2020-04-08 19:24:03 +08:00
|
|
|
func getResponseBody(resp *http.Response) string {
|
|
|
|
contentType := resp.Header.Get("Content-Type")
|
|
|
|
if !ifDumpBody(contentType) {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
bytesBody, errReadBody := ioutil.ReadAll(resp.Body)
|
|
|
|
if errReadBody != nil {
|
|
|
|
return ""
|
|
|
|
}
|
2020-04-24 00:00:52 +08:00
|
|
|
// So the response body can be read again.
|
2020-04-08 19:24:03 +08:00
|
|
|
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bytesBody))
|
|
|
|
return gconv.UnsafeBytesToStr(bytesBody)
|
|
|
|
}
|
|
|
|
|
2020-04-24 00:00:52 +08:00
|
|
|
// RawRequest returns the raw content of the request.
|
2020-04-08 19:24:03 +08:00
|
|
|
func (r *ClientResponse) RawRequest() string {
|
2020-04-11 12:16:53 +08:00
|
|
|
// ClientResponse can be nil.
|
2020-04-08 20:11:06 +08:00
|
|
|
if r == nil {
|
|
|
|
return ""
|
|
|
|
}
|
2020-04-24 00:00:52 +08:00
|
|
|
if r.request == nil {
|
2020-04-08 19:24:03 +08:00
|
|
|
return ""
|
|
|
|
}
|
2020-04-11 12:16:53 +08:00
|
|
|
// DumpRequestOut writes more request headers than DumpRequest, such as User-Agent.
|
2020-04-24 00:00:52 +08:00
|
|
|
bs, err := httputil.DumpRequestOut(r.request, false)
|
2020-04-08 19:24:03 +08:00
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
2020-04-24 00:00:52 +08:00
|
|
|
return fmt.Sprintf(
|
|
|
|
dumpTextFormat,
|
|
|
|
"REQUEST ",
|
|
|
|
gconv.UnsafeBytesToStr(bs),
|
|
|
|
getRequestBody(r.request),
|
|
|
|
)
|
2020-04-08 19:24:03 +08:00
|
|
|
}
|
|
|
|
|
2020-04-24 00:00:52 +08:00
|
|
|
// RawResponse returns the raw content of the response.
|
2020-04-08 19:24:03 +08:00
|
|
|
func (r *ClientResponse) RawResponse() string {
|
2020-04-11 12:16:53 +08:00
|
|
|
// ClientResponse can be nil.
|
2020-04-08 19:24:03 +08:00
|
|
|
if r == nil || r.Response == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
bs, err := httputil.DumpResponse(r.Response, false)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2020-04-24 00:00:52 +08:00
|
|
|
return fmt.Sprintf(
|
|
|
|
dumpTextFormat,
|
|
|
|
"RESPONSE",
|
|
|
|
gconv.UnsafeBytesToStr(bs),
|
|
|
|
getResponseBody(r.Response),
|
|
|
|
)
|
2020-04-08 19:24:03 +08:00
|
|
|
}
|
|
|
|
|
2020-04-11 12:16:53 +08:00
|
|
|
// Raw returns the raw text of the request and the response.
|
2020-04-08 19:24:03 +08:00
|
|
|
func (r *ClientResponse) Raw() string {
|
|
|
|
return fmt.Sprintf("%s\n%s", r.RawRequest(), r.RawResponse())
|
|
|
|
}
|