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

feat(curl): generate curl cmd for request && example for curl cmd #794

Merged
merged 3 commits into from
Jun 28, 2024

Conversation

ahuigo
Copy link
Contributor

@ahuigo ahuigo commented May 11, 2024

I've extracted curl code from my previous PR(#734).
Could you review this code?

New feature: generate curl command

Example: https://github.com/ahuigo/resty/blob/curl/v2/examples/debug_curl_test.go

client := resty.New()
resp, err := client.R().EnableTrace().
    Get("https://httpbin.org/get")

// Explore curl command
curlCmdExecuted := resp.Request.GenerateCurlCommand()
fmt.Println("Curl Command:", curlCmdExecuted)

Output

$ go test -run '^TestDebugCurl$' github.com/go-resty/resty/v2/examples -v
=== RUN   TestDebugCurl
    debug_curl_test.go:29: curlCmdUnexecuted:  
    curl -X GET -H 'Content-Type: application/json' -H 'Cookie: count=1' -H 'User-Agent: go-resty/2.12.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' 'http://unexecuted-url'

    debug_curl_test.go:41: curlCmdExecuted:  
    curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Cookie: count=1; count=1' -H 'User-Agent: go-resty/2.12.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' http://127.0.0.1:56426/post
--- PASS: TestDebugCurl (0.00s)

@luengwaiban
Copy link

this PR is very needed!!

Copy link
Member

@jeevatkm jeevatkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo - I'm sorry for the delayed response.

Thanks for extracting and creating a new PR. I have added my comments; could you update the PR? and then we can merge it.

util_curl.go Outdated
"github.com/go-resty/resty/v2/shellescape"
)

func BuildCurlRequest(req *http.Request, httpCookiejar http.CookieJar) (curl string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo, please un-export this method to the package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

request.go Outdated
@@ -333,6 +348,12 @@ func (r *Request) SetResult(res interface{}) *Request {
return r
}

// This method is to register curl cmd for request executed.
func (r *Request) SetResultCurlCmd(curlCmd *string) *Request {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo - please remove this method and the related implementation code.

Resty could provide a cURL command generation on-demand instead of implicit via -

resp, err := client.R().
     EnableTrace().
     Get("https://httpbin.org/get")

curlCmd := resp.Request.GenerateCurlCommand()

Copy link
Contributor Author

@ahuigo ahuigo Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done this as you said.

It needs to be explained that without SetResultCurlCmd, GenerateCurlCommand must rely on EnableTrace.

This is because if EnableTrace() is not called, GenerateCurlCommand cannot obtain the body.

request.go Outdated
@@ -73,6 +74,20 @@ type Request struct {
retryConditions []RetryConditionFunc
}

func (r *Request) GetCurlCmd() string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Please refactor this method with the name GenerateCurlCommand and update this method logic to on-demand cURL command generation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -307,6 +307,13 @@ func addCredentials(c *Client, r *Request) error {
return nil
}

func createCurlCmd(c *Client, r *Request) (err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Please remove this middleware.

Copy link
Contributor Author

@ahuigo ahuigo Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting this middleware will cause GenerateCurlCommand to be unable to get the body (because resty will delete the body after executing the request)

	// 3. Generate curl body
	if req.Body != nil {
		buf, _ := io.ReadAll(req.Body)
		req.Body = io.NopCloser(bytes.NewBuffer(buf)) // important!!
		curl += `-d ` + shellescape.Quote(string(buf))
	}

Considering that I need to record body before the request is executed(only when EnableTrace() is called),
I need to read body in middleware.

func createCurlCmd(c *Client, r *Request) (err error) {
	if r.trace {
		if r.resultCurlCmd==nil{
			r.resultCurlCmd = new(string)
		}
		*r.resultCurlCmd = buildCurlRequest(r.RawRequest, c.httpClient.Jar)
	}
	return nil
}

I think the best time to record the body is when the middleware request occurs.

  • If it is before the middleware, parameters such as url and authorization will be lost.
  • If it is after the middleware, the body parameters will be lost.

Do you have any other better suggestions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo I understand. For now, keep this conditional execution for createCurlCmd method with r.trace enabled. I will see what could be improved in v3.

@@ -1396,6 +1403,7 @@ func createClient(hc *http.Client) *Client {
parseRequestBody,
createHTTPRequest,
addCredentials,
createCurlCmd,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Please remove this middleware.

@ahuigo ahuigo force-pushed the curl/v2 branch 2 times, most recently from 8de5faf to b2969a3 Compare June 19, 2024 07:07
Copy link
Member

@jeevatkm jeevatkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Thanks for incorporating the review comments. I have added one new comment in the shellescape.go file. Please have a look.

@@ -307,6 +307,13 @@ func addCredentials(c *Client, r *Request) error {
return nil
}

func createCurlCmd(c *Client, r *Request) (err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo I understand. For now, keep this conditional execution for createCurlCmd method with r.trace enabled. I will see what could be improved in v3.

The original Python package which this work was inspired by can be found
at https://pypi.python.org/pypi/shellescape.
*/
package shellescape // "import gopkg.in/alessio/shellescape.v1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Can we remove this line?
On the line, godoc has different meanings to it.

// "import gopkg.in/alessio/shellescape.v1"

If we learned something from this gopkg.in/alessio/shellescape.v1 library, please capture that acknowledgment in the above godoc instead of here.
Otherwise remove it.

jeevatkm
jeevatkm previously approved these changes Jun 28, 2024
Copy link
Member

@jeevatkm jeevatkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahuigo Thanks for updating PR and your contribution.

@jeevatkm
Copy link
Member

@ahuigo It seems the PR check build failed at gofmt - can you have a look?
https://github.com/go-resty/resty/actions/runs/9594966759/job/26791514646?pr=794

1. refactor `GetCurlCommand` with the name `GenerateCurlCommand`
2. un-export this method `BuildCurlRequest`
3. remove SetResultCurlCmd
@ahuigo
Copy link
Contributor Author

ahuigo commented Jun 28, 2024

@ahuigo It seems the PR check build failed at gofmt - can you have a look? https://github.com/go-resty/resty/actions/runs/9594966759/job/26791514646?pr=794

@jeevatkm Fixed

jeevatkm
jeevatkm previously approved these changes Jun 28, 2024
Copy link

codecov bot commented Jun 28, 2024

Codecov Report

Attention: Patch coverage is 98.66667% with 1 line in your changes missing coverage. Please review.

Project coverage is 96.67%. Comparing base (baf7c12) to head (eeb7d8e).

Files Patch % Lines
client.go 90.90% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##               v2     #794      +/-   ##
==========================================
+ Coverage   96.53%   96.67%   +0.13%     
==========================================
  Files          12       14       +2     
  Lines        1673     1742      +69     
==========================================
+ Hits         1615     1684      +69     
  Misses         37       37              
  Partials       21       21              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jeevatkm
Copy link
Member

@ahuigo Please see - https://github.com/go-resty/resty/pull/794/checks?check_run_id=26793372890

@ahuigo
Copy link
Contributor Author

ahuigo commented Jun 28, 2024

@jeevatkm Fixed.
Since the unit test code of the /examples/* is in a different package from the source code, coverage does not calculate imported packages by default.

examples/debug_curl_test.go // import different package("github.com/go-resty/resty/v2")

In order to allow coverage to calculate imported packages, we need to add this parameter( -coverpkg=./...):

# go test ./... -race -coverprofile=coverage.txt
go test ./... -race -coverprofile=coverage.txt -coverpkg=./...

…kages that are imported in different packages
Copy link
Member

@jeevatkm jeevatkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @ahuigo, for taking care of the test and CI argument.

@jeevatkm jeevatkm merged commit 855d418 into go-resty:v2 Jun 28, 2024
3 checks passed
renovate bot added a commit to Michsior14/transmission-gluetun-port-update that referenced this pull request Aug 5, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [github.com/go-resty/resty/v2](https://togithub.com/go-resty/resty) |
`v2.13.1` -> `v2.14.0` |
[![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fgo-resty%2fresty%2fv2/v2.14.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2fgo-resty%2fresty%2fv2/v2.14.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2fgo-resty%2fresty%2fv2/v2.13.1/v2.14.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fgo-resty%2fresty%2fv2/v2.13.1/v2.14.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>go-resty/resty (github.com/go-resty/resty/v2)</summary>

###
[`v2.14.0`](https://togithub.com/go-resty/resty/releases/tag/v2.14.0)

[Compare
Source](https://togithub.com/go-resty/resty/compare/v2.13.1...v2.14.0)

### Release Notes

#### New Features

- feat(curl): generate curl cmd for request && example for curl cmd by
[@&#8203;ahuigo](https://togithub.com/ahuigo) in
[go-resty/resty#794

#### Enhancements

- build: update bazel config with new files by
[@&#8203;jeevatkm](https://togithub.com/jeevatkm) in
[go-resty/resty#800
- chore: dependency and version update v2.14.0 by
[@&#8203;jeevatkm](https://togithub.com/jeevatkm) in
[go-resty/resty#816

#### Upstream Fixes

- update net package for vuln CVE-2023-45288 by
[@&#8203;shedyfreak](https://togithub.com/shedyfreak) in
[go-resty/resty#804

#### Test Cases

- fix(examples): wrongly stderr written as stdout by
[@&#8203;ahuigo](https://togithub.com/ahuigo) in
[go-resty/resty#801

#### Documentation

- fix: change resty.GET to resty.MethodGet in doc comment by
[@&#8203;autopp](https://togithub.com/autopp) in
[go-resty/resty#803
- resty dev version number and year update by
[@&#8203;jeevatkm](https://togithub.com/jeevatkm) in
[go-resty/resty#799

#### New Contributors

- [@&#8203;ahuigo](https://togithub.com/ahuigo) made their first
contribution in
[go-resty/resty#794
- [@&#8203;autopp](https://togithub.com/autopp) made their first
contribution in
[go-resty/resty#803
- [@&#8203;shedyfreak](https://togithub.com/shedyfreak) made their first
contribution in
[go-resty/resty#804

**Full Changelog**:
go-resty/resty@v2.13.1...v2.14.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View the
[repository job
log](https://developer.mend.io/github/Michsior14/transmission-gluetun-port-update).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants