#591 add Raw* method in ClientResponse to get request and response string

This commit is contained in:
linx 2020-04-08 19:24:03 +08:00
parent ccceeae29c
commit 15672e7a09
2 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,107 @@
// 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"
)
const dumpTextFormat = `+---------------------------------------------+
| ghttp %s |
+---------------------------------------------+
%s
%s
`
func ifDumpBody(contentType string) bool {
// only dump body when contentType in.
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
}
// getRequestBody return request body string.
// if error occurs, return empty string
func getRequestBody(req *http.Request) string {
contentType := req.Header.Get("Content-Type")
if !ifDumpBody(contentType) {
return ""
}
// must use this method for reading the body more than once
bodyReader, errGetBody := req.GetBody()
if errGetBody != nil {
return ""
}
bytesBody, errReadBody := ioutil.ReadAll(bodyReader)
if errReadBody != nil {
return ""
}
return gconv.UnsafeBytesToStr(bytesBody)
}
// getResponseBody return response body string.
// if error occurs, return empty string
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 ""
}
// for reading the body more than once
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bytesBody))
return gconv.UnsafeBytesToStr(bytesBody)
}
// RawRequest dump request to raw string
func (r *ClientResponse) RawRequest() string {
// this can be nil
if r == nil || r.Request == nil {
return ""
}
// DumpRequestOut will write more header than DumpRequest, such as User-Agent.
// read body using getRequestBody method.
bs, err := httputil.DumpRequestOut(r.Request, false)
if err != nil {
return ""
}
return fmt.Sprintf(dumpTextFormat, "REQUEST ", gconv.UnsafeBytesToStr(bs), getRequestBody(r.Request))
}
// RawResponse dump response to raw string
func (r *ClientResponse) RawResponse() string {
// this can be nil
if r == nil || r.Response == nil {
return ""
}
// read body using getResponseBody method.
bs, err := httputil.DumpResponse(r.Response, false)
if err != nil {
return ""
}
return fmt.Sprintf(dumpTextFormat, "RESPONSE", gconv.UnsafeBytesToStr(bs), getResponseBody(r.Response))
}
// Raw dump request and response string
func (r *ClientResponse) Raw() string {
return fmt.Sprintf("%s\n%s", r.RawRequest(), r.RawResponse())
}

View File

@ -0,0 +1,57 @@
// 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_test
import (
"fmt"
"testing"
"time"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/text/gstr"
)
func Test_Client_Request_13_Dump(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/hello", func(r *ghttp.Request) {
r.Response.WriteHeader(200)
r.Response.WriteJson(g.Map{"field": "test_for_response_body"})
})
s.BindHandler("/hello2", func(r *ghttp.Request) {
r.Response.WriteHeader(200)
r.Response.Writeln(g.Map{"field": "test_for_response_body"})
})
s.SetPort(p)
s.SetDumpRouterMap(false)
s.Start()
defer s.Shutdown()
time.Sleep(100 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
url := fmt.Sprintf("http://127.0.0.1:%d", p)
client := ghttp.NewClient().SetPrefix(url).ContentJson()
r, err := client.Post("/hello", g.Map{"field": "test_for_request_body"})
t.Assert(err, nil)
dumpedText := r.RawRequest()
t.Assert(gstr.Contains(dumpedText, "test_for_request_body"), true)
dumpedText2 := r.RawResponse()
t.Assert(gstr.Contains(dumpedText2, "test_for_response_body"), true)
client2 := ghttp.NewClient().SetPrefix(url).ContentType("text/html")
r2, err := client2.Post("/hello2", g.Map{"field": "test_for_request_body"})
t.Assert(err, nil)
dumpedText3 := r2.RawRequest()
t.Assert(gstr.Contains(dumpedText3, "test_for_request_body"), false)
dumpedText4 := r2.RawResponse()
t.Assert(gstr.Contains(dumpedText4, "test_for_request_body"), false)
})
}