Skip to content

Commit

Permalink
fix(enhancement): add explicit option to enable generate curl command…
Browse files Browse the repository at this point in the history
… in conjunction with debug mode and few clean ups #828 (#842)
  • Loading branch information
jeevatkm authored Sep 3, 2024
1 parent 08e6170 commit 370d744
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 210 deletions.
31 changes: 25 additions & 6 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ type Client struct {
invalidHooks []ErrorHook
panicHooks []ErrorHook
rateLimiter RateLimiter
generateCurlOnDebug bool
}

// User type is to hold an username and password information
Expand Down Expand Up @@ -443,12 +444,13 @@ func (c *Client) R() *Request {
RawPathParams: map[string]string{},
Debug: c.Debug,

client: c,
multipartFiles: []*File{},
multipartFields: []*MultipartField{},
jsonEscapeHTML: c.jsonEscapeHTML,
log: c.log,
responseBodyLimit: c.ResponseBodyLimit,
client: c,
multipartFiles: []*File{},
multipartFields: []*MultipartField{},
jsonEscapeHTML: c.jsonEscapeHTML,
log: c.log,
responseBodyLimit: c.ResponseBodyLimit,
generateCurlOnDebug: c.generateCurlOnDebug,
}
return r
}
Expand Down Expand Up @@ -1130,6 +1132,23 @@ func (c *Client) DisableTrace() *Client {
return c
}

// EnableGenerateCurlOnDebug method enables the generation of CURL commands in the debug log.
// It works in conjunction with debug mode.
//
// NOTE: Use with care.
// - Potential to leak sensitive data in the debug log from [Request] and [Response].
// - Beware of memory usage since the request body is reread.
func (c *Client) EnableGenerateCurlOnDebug() *Client {
c.generateCurlOnDebug = true
return c
}

// DisableGenerateCurlOnDebug method disables the option set by [Client.EnableGenerateCurlOnDebug].
func (c *Client) DisableGenerateCurlOnDebug() *Client {
c.generateCurlOnDebug = false
return c
}

// IsProxySet method returns the true is proxy is set from resty client otherwise
// false. By default proxy is set from environment, refer to `http.ProxyFromEnvironment`.
func (c *Client) IsProxySet() bool {
Expand Down
36 changes: 20 additions & 16 deletions examples/debug_curl_test.go → curl_cmd_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
package examples
package resty

import (
"io"
"net/http"
"os"
"strings"
"testing"

"github.com/go-resty/resty/v2"
)

// 1. Generate curl for unexecuted request(dry-run)
func TestGenerateUnexcutedCurl(t *testing.T) {
ts := createHttpbinServer(0)
defer ts.Close()

req := resty.New().R().
func TestGenerateUnexecutedCurl(t *testing.T) {
req := dclr().
SetBody(map[string]string{
"name": "Alex",
}).
Expand All @@ -25,7 +20,8 @@ func TestGenerateUnexcutedCurl(t *testing.T) {
},
)

curlCmdUnexecuted := req.GenerateCurlCommand()
curlCmdUnexecuted := req.EnableGenerateCurlOnDebug().GenerateCurlCommand()
req.DisableGenerateCurlOnDebug()

if !strings.Contains(curlCmdUnexecuted, "Cookie: count=1") ||
!strings.Contains(curlCmdUnexecuted, "curl -X GET") ||
Expand All @@ -39,28 +35,32 @@ func TestGenerateUnexcutedCurl(t *testing.T) {

// 2. Generate curl for executed request
func TestGenerateExecutedCurl(t *testing.T) {
ts := createHttpbinServer(0)
ts := createPostServer(t)
defer ts.Close()

data := map[string]string{
"name": "Alex",
}
req := resty.New().R().
c := dcl()
req := c.R().
SetBody(data).
SetCookies(
[]*http.Cookie{
{Name: "count", Value: "1"},
},
)

url := ts.URL + "/post"
url := ts.URL + "/curl-cmd-post"
resp, err := req.
EnableTrace().
EnableGenerateCurlOnDebug().
Post(url)
if err != nil {
t.Fatal(err)
}
curlCmdExecuted := resp.Request.GenerateCurlCommand()

c.DisableGenerateCurlOnDebug()
req.DisableGenerateCurlOnDebug()
if !strings.Contains(curlCmdExecuted, "Cookie: count=1") ||
!strings.Contains(curlCmdExecuted, "curl -X POST") ||
!strings.Contains(curlCmdExecuted, `-d '{"name":"Alex"}'`) ||
Expand All @@ -73,15 +73,16 @@ func TestGenerateExecutedCurl(t *testing.T) {

// 3. Generate curl in debug mode
func TestDebugModeCurl(t *testing.T) {
ts := createHttpbinServer(0)
ts := createPostServer(t)
defer ts.Close()

// 1. Capture stderr
getOutput, restore := captureStderr()
defer restore()

// 2. Build request
req := resty.New().R().
c := New()
req := c.EnableGenerateCurlOnDebug().R().
SetBody(map[string]string{
"name": "Alex",
}).
Expand All @@ -92,12 +93,15 @@ func TestDebugModeCurl(t *testing.T) {
)

// 3. Execute request: set debug mode
url := ts.URL + "/post"
url := ts.URL + "/curl-cmd-post"
_, err := req.SetDebug(true).Post(url)
if err != nil {
t.Fatal(err)
}

c.DisableGenerateCurlOnDebug()
req.DisableGenerateCurlOnDebug()

// 4. test output curl
output := getOutput()
if !strings.Contains(output, "Cookie: count=1") ||
Expand Down
10 changes: 0 additions & 10 deletions examples/BUILD.bazel

This file was deleted.

162 changes: 0 additions & 162 deletions examples/server_test.go

This file was deleted.

14 changes: 9 additions & 5 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ func addCredentials(c *Client, r *Request) error {
}

func createCurlCmd(c *Client, r *Request) (err error) {
if r.trace {
if r.Debug && r.generateCurlOnDebug {
if r.resultCurlCmd == nil {
r.resultCurlCmd = new(string)
}
Expand Down Expand Up @@ -338,10 +338,14 @@ func requestLogger(c *Client, r *Request) error {
}
}

reqLog := "\n==============================================================================\n" +
"~~~ REQUEST(curl) ~~~\n" +
fmt.Sprintf("CURL:\n %v\n", buildCurlRequest(r.RawRequest, r.client.httpClient.Jar)) +
"~~~ REQUEST ~~~\n" +
reqLog := "\n==============================================================================\n"

if r.Debug && r.generateCurlOnDebug {
reqLog += "~~~ REQUEST(CURL) ~~~\n" +
fmt.Sprintf(" %v\n", *r.resultCurlCmd)
}

reqLog += "~~~ REQUEST ~~~\n" +
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) +
Expand Down
Loading

0 comments on commit 370d744

Please sign in to comment.