Skip to content

Commit

Permalink
example: add examples about ssl, debug, curl, trace, error, etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuigo committed Oct 16, 2023
1 parent 105f718 commit c12a824
Show file tree
Hide file tree
Showing 30 changed files with 1,763 additions and 9 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Expand Up @@ -26,5 +26,8 @@ _testmain.go
coverage.out
coverage.txt

# Exclude intellij IDE folders
# Exclude IDE folders
.idea/*
.vscode/*
__debug_bin
.DS_Store
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -126,12 +126,17 @@ import "github.com/go-resty/resty/v2"

```go
// Create a Resty Client
var curlCmdExecuted string
client := resty.New()

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

// Explore curl command
fmt.Println("Curl Command:", curlCmdExecuted)

// Explore response object
fmt.Println("Response Info:")
fmt.Println(" Error :", err)
Expand Down
24 changes: 16 additions & 8 deletions client.go
Expand Up @@ -1129,9 +1129,7 @@ func (c *Client) GetClient() *http.Client {
// Client Unexported methods
//_______________________________________________________________________

// Executes method executes the given `Request` object and returns response
// error.
func (c *Client) execute(req *Request) (*Response, error) {
func (c *Client) executeBefore(req *Request) (error) {
// Lock the user-defined pre-request hooks.
c.udBeforeRequestLock.RLock()
defer c.udBeforeRequestLock.RUnlock()
Expand All @@ -1147,22 +1145,22 @@ func (c *Client) execute(req *Request) (*Response, error) {
// to modify the *resty.Request object
for _, f := range c.udBeforeRequest {
if err = f(c, req); err != nil {
return nil, wrapNoRetryErr(err)
return wrapNoRetryErr(err)
}
}

// If there is a rate limiter set for this client, the Execute call
// will return an error if the rate limit is exceeded.
if req.client.rateLimiter != nil {
if !req.client.rateLimiter.Allow() {
return nil, wrapNoRetryErr(ErrRateLimitExceeded)
return wrapNoRetryErr(ErrRateLimitExceeded)
}
}

// resty middlewares
for _, f := range c.beforeRequest {
if err = f(c, req); err != nil {
return nil, wrapNoRetryErr(err)
return wrapNoRetryErr(err)
}
}

Expand All @@ -1173,15 +1171,24 @@ func (c *Client) execute(req *Request) (*Response, error) {
// call pre-request if defined
if c.preReqHook != nil {
if err = c.preReqHook(c, req.RawRequest); err != nil {
return nil, wrapNoRetryErr(err)
return wrapNoRetryErr(err)
}
}

if err = requestLogger(c, req); err != nil {
return nil, wrapNoRetryErr(err)
return wrapNoRetryErr(err)
}

req.RawRequest.Body = newRequestBodyReleaser(req.RawRequest.Body, req.bodyBuf)
return nil
}

// Executes method executes the given `Request` object and returns response
// error.
func (c *Client) execute(req *Request) (*Response, error) {
if err:= c.executeBefore(req);err!=nil{
return nil, err
}

req.Time = time.Now()
resp, err := c.httpClient.Do(req.RawRequest)
Expand Down Expand Up @@ -1375,6 +1382,7 @@ func createClient(hc *http.Client) *Client {
parseRequestBody,
createHTTPRequest,
addCredentials,
createCurlCmd,
}

// user defined request middlewares
Expand Down
19 changes: 19 additions & 0 deletions conf/nginx.crt
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDIjCCAgqgAwIBAgIUPkbRM1znk+3fLI8g5eB5i8Ie3K0wDQYJKoZIhvcNAQEL
BQAwFTETMBEGA1UEAwwKbG9jYWwuc2VsZjAeFw0yMzAzMjgwMzQ1MDlaFw0yNDAz
MjcwMzQ1MDlaMBUxEzARBgNVBAMMCmxvY2FsLnNlbGYwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDIdnZmgBgAGOChpZGwikpQgTRTkqFNKQV5jRQXr7r7
3xV+PilkDShz+UWfYG3zszLX7L9jllIDj1V5YALV+f3tjDaPnptSUnNIKIdjripQ
ojX5639oCmHA4ZnYbDxx8GcNlfOLGW4oAVuY9PHaL69nmrHq58wQX2VPR6jCjzCY
T0putkMCRbCTbzeb0ntcEHNKrVuk8TlLxGnNNXyeF1BS6YHa9/3PwXmwsApZ1fY2
KepHclqVISz+E0Cj4KkVvGI++9KBBDcNMEyerhU0ocotXoqQxQKm+eeED44LKnnh
czPION+xRTfsqn+j8AyrShY+JkBt+VseOlOeNpn25p5dAgMBAAGjajBoMB0GA1Ud
DgQWBBQ8aBcGhCLZzEGztBxgChe+zIY88TAfBgNVHSMEGDAWgBQ8aBcGhCLZzEGz
tBxgChe+zIY88TAPBgNVHRMBAf8EBTADAQH/MBUGA1UdEQQOMAyCCmxvY2FsLnNl
bGYwDQYJKoZIhvcNAQELBQADggEBAHBKNQHNBlRdI6cICeEkBYpoJRg1UBCEpxPo
A7He5EN1vZReJcMoFoc86tPsvUaIwsgqiEu6S0sQNahJHKF0FwcB+A6F9kQmW7si
CrQw9hHneooEmYs2CldNV4w51HWKNDZ5Ra+gH5B2AKR1EWFDh4MMzPlL2MPgasFC
OeAOFrftD8hLLSvCvDsIall/pOg6wTP5vimndsjw+fPk7/SRAqZZzM1EQ4WZ7uZq
oRXdSOhtfyEZYsC04VQNT0KAD+m73ctYXn4EHRpHx5tA1ZkKuuOLOXSVYmHRkk72
ReutF5Khp+XIjc77fHX6KRCWxT/KE23a4aEmmJzKhV3A1bcvpQ4=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions conf/nginx.key
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDIdnZmgBgAGOCh
pZGwikpQgTRTkqFNKQV5jRQXr7r73xV+PilkDShz+UWfYG3zszLX7L9jllIDj1V5
YALV+f3tjDaPnptSUnNIKIdjripQojX5639oCmHA4ZnYbDxx8GcNlfOLGW4oAVuY
9PHaL69nmrHq58wQX2VPR6jCjzCYT0putkMCRbCTbzeb0ntcEHNKrVuk8TlLxGnN
NXyeF1BS6YHa9/3PwXmwsApZ1fY2KepHclqVISz+E0Cj4KkVvGI++9KBBDcNMEye
rhU0ocotXoqQxQKm+eeED44LKnnhczPION+xRTfsqn+j8AyrShY+JkBt+VseOlOe
Npn25p5dAgMBAAECggEAYB1AdrPbDgzfg1Gt0V309LWGX72xvhu5hsaoSBUXS5Vy
KjXmxZRzfWuawKhM/6g/a/0U5MxZpWBPhKMOqQa0g/WS4XiUEzv6DzJze80xd7jW
tW3/B+TWatMgXv7CWoT//CkV/O8j/GVuRB/JaCot6ThoLu+VzZHXstPya9qY26Vr
Evc6NF+MED/n2ciagBAJzSEG0L8Ry948Vbzz3yEu1p9Mdg31AVWu6/m4LfMWB7km
rtpSiPdZwqVCsTjGRb2T4hF3TmMgBC1+0meDMxd33xws1XaOoGwaqwdgMpIdowTK
DBonkT10De6cqjtVg/IqeZvmCZl4al4lkSzfGtwGRwKBgQDyx0kQw8D6PpMQ4YSk
cFgVgEwJ2ED2yVlOqnOpw+cFG+k9AlS9VuLOYDyuxsLCX4VdbGitmBnd70E3Zpnj
V74Tqu+nnUr/i8BDl8XG+EceBW+xpMgVIaMnKHbWa3RcIKU4CALbtDL0sl8l96Ch
NxjNje3E/E9hmAeFSBr6zsqPEwKBgQDTYTqzGMeBk7oNE0YonR8UxX1Ah5tSU9Eu
usY1vYGv3FoeJR1RexN7+o4rFxVN+cVy3Mwpml1ptPRZP1V3NGZCCObOaOU4Pplt
HjzhClBTeIsbmZ1Bq/MoRaXp4yykPkHaniR+d7/GjwnSrIzyupsWAe2fPfeIx1/K
VFg1eLcazwKBgQCuv/16wLy2I7ZuDzYPuwHcMCYLbAqO2K2c7xokF2vBhK6lCHmA
c/r7e9ASKeVkTadMcM0ELxhnZGD4BLU+LBkYRREOAC1MtgYlYSiuKGXgWR9lqeuP
MlAizoCDpIL0EVd7dmDATfvjoETWqmCHyoXi54c/JDHrWKgJKrao05J/2wKBgDxu
H4n0G5U/1oDGcdhKkwgtLZG1MwJmU/c4DlJuyxSrulfD5I3W0csv5lULVFvmfDxK
Q1PhfbMquHCLWrOpl1JpmRKJin555wL7EgyEFlLGs35AfGS589ofjz8+YxTRd6I4
c9Z0Ba+OVRCVo/YAwzWXd4d+/7VqykfdtRoUWMShAoGAVamX3xdVKVUH1vkbcW47
MZMvli5qeWFKkjNYzAIkHCOKgP+LcOhj2yywSliXZjBP3/AM4IyTf85rL7WWUHs9
M9V6iy4s0v95+NQ3gBhU8dqGZMlMAfHTdOYP5QZWKQQfF0iGHDH6faEsdBBWiqhI
laxSnUjUN5VMS/ViBExyBQs=
-----END PRIVATE KEY-----
32 changes: 32 additions & 0 deletions examples/auth_test.go
@@ -0,0 +1,32 @@
package examples

import (
"strings"
"testing"

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

// Example about sending Authentication header
func TestAuth(t *testing.T) {
var curlCmdExecuted string
ts := createEchoServer()
defer ts.Close()
// Test authentication usernae and password
client := resty.New()
resp, err := client.R().
SetBasicAuth("USER", "PASSWORD").
SetResultCurlCmd(&curlCmdExecuted).
Get( ts.URL+"/echo",)
if err != nil {
t.Fatal(err)
}

if !strings.Contains(curlCmdExecuted, "Authorization: Basic ") {
t.Fatal("bad curl:", curlCmdExecuted)
}
if !strings.Contains(string(resp.Body()), "Authorization: Basic ") {
t.Fatal("bad auth body:\n" + resp.String())
}
t.Log(curlCmdExecuted)
}
120 changes: 120 additions & 0 deletions examples/context_test.go
@@ -0,0 +1,120 @@
package examples

import (
"context"
"net/http"
"net/http/httptrace"
"testing"
"time"

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

// Example about cancel request with context
func TestSetContextCancelMulti(t *testing.T) {
// 0. Init test server
ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Microsecond)
n, err := w.Write([]byte("TestSetContextCancel: response"))
t.Logf("%s Server: wrote %d bytes", time.Now(), n)
t.Logf("%s Server: err is %v ", time.Now(), err)
}, 0)
defer ts.Close()

// 1. Create client
ctx, cancel := context.WithCancel(context.Background())
client := resty.New().R().SetContext(ctx)
go func() {
time.Sleep(1 * time.Microsecond)
cancel()
}()

// 2. First request
_, err := client.Get(ts.URL + "/get")
if !errIsContextCancel(err) {
t.Fatalf("Got unexpected error: %v", err)
}

// 3. Second request
_, err = client.Get(ts.URL + "/get")
if !errIsContextCancel(err) {
t.Fatalf("Got unexpected error: %v", err)
}
}

// Test context: cancel with chan
func TestSetContextCancelWithChan(t *testing.T) {
ch := make(chan struct{})
ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
defer func() {
ch <- struct{}{} // tell test request is finished
}()
t.Logf("%s Server: %v %v", time.Now(), r.Method, r.URL.Path)
ch <- struct{}{} // tell test request is canceld
t.Logf("%s Server: call canceld", time.Now())

<-ch // wait for client to finish request
n, err := w.Write([]byte("TestSetContextCancel: response"))
// FIXME? test server doesn't handle request cancellation
t.Logf("%s Server: wrote %d bytes", time.Now(), n)
t.Logf("%s Server: err is %v ", time.Now(), err)

}, 0)
defer ts.Close()

ctx, cancel := context.WithCancel(context.Background())
go func() {
<-ch // wait for server to start request handling
cancel()
}()

_, err := resty.New().R().SetContext(ctx).Get(ts.URL + "/get")
t.Logf("%s:client:is canceled", time.Now())

ch <- struct{}{} // tell server to continue request handling
t.Logf("%s:client:tell server to continue", time.Now())

<-ch // wait for server to finish request handling

if !errIsContextCancel(err) {
t.Fatalf("Got unexpected error: %v", err)
}
}

// test with trace context
func TestContextWithTrace(t *testing.T) {
ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("TestSetContextWithTrace: response"))
}, 0)
defer ts.Close()

//1. Create Trace context
traceInfo := struct {
dnsDone time.Time
connectDone time.Time
}{}

trace := &httptrace.ClientTrace{
ConnectStart: func(network, addr string) {
traceInfo.dnsDone = time.Now()
t.Log(time.Now(), "ConnectStart:", "network=", network, ",addr=", addr)
},
ConnectDone: func(network, addr string, err error) {
traceInfo.connectDone = time.Now()
t.Log(time.Now(), "ConnectDone:", "network=", network, ",addr=", addr)
},
}
ctx := httptrace.WithClientTrace(context.Background(), trace)

//2. Send request with Trace context
session := resty.New().R().SetContext(ctx)
params := MapString{"name": "ahuigo", "page": "1"}
_, err := session.SetQueryParams(params).Get(ts.URL+"/get")
if err != nil {
t.Fatal(err)
}
if traceInfo.connectDone.Sub(traceInfo.dnsDone) <= 0 {
t.Fatal("Bad trace info")
}

}

0 comments on commit c12a824

Please sign in to comment.