Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(enhancement): add explicit option to enable generate curl command in conjunction with debug mode and few clean ups #828 #842

Merged
merged 1 commit into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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