Skip to content
Open
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
16 changes: 8 additions & 8 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@ func NewClient(setters ...ClientOption) *Client {

// request is the common func to send an HTTP request.
func (c *Client) request(method, url string, opts *Options, body []byte) (*Response, error) {
r, err := newRequest(method, url, opts, body)
ctx := opts.ctx
if opts.Timeout > 0 { // ctx with timeout if specified
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, opts.Timeout)
defer cancel()
}
r, err := newRequest(ctx, method, url, opts, body)
if err != nil {
return nil, err
}
Expand All @@ -62,12 +68,6 @@ func (c *Client) request(method, url string, opts *Options, body []byte) (*Respo
}
*r.opts.DumpRequestOut = string(reqDump)
}
ctx := opts.ctx
if opts.Timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, opts.Timeout)
defer cancel()
}
var interceptors []InterceptorFunc
if r.opts.Interceptor != nil {
interceptors = append(interceptors, r.opts.Interceptor)
Expand All @@ -84,7 +84,7 @@ func (c *Client) request(method, url string, opts *Options, body []byte) (*Respo

// do sends an HTTP request and returns an HTTP response, following policy
// (such as redirects, cookies, auth) as configured on the client.
func (c *Client) do(ctx context.Context, r *Request) (*Response, error) {
func (c *Client) do(_ context.Context, r *Request) (*Response, error) {
// If the returned error is nil, the Response will contain
// a non-nil Body which the user is expected to close.
resp, err := c.client.Do(r.Request)
Expand Down
7 changes: 3 additions & 4 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,7 @@ func BasicAuth(username, password string) Option {
}
}

// Timeout creates a new context with specified timeout for
// the current request.
// Timeout sets the HTTP request context timeout by [context.WithTimeout].
func Timeout(timeout time.Duration) Option {
return func(opts *Options) {
opts.Timeout = timeout
Expand All @@ -343,8 +342,8 @@ func Timeout(timeout time.Duration) Option {
// input param (req or resp) if not nil.
//
// Refer:
// - https://pkg.go.dev/net/http/httputil#DumpRequestOut
// - https://pkg.go.dev/net/http/httputil#DumpResponse
// - https://pkg.go.dev/net/http/httputil#DumpRequestOut
// - https://pkg.go.dev/net/http/httputil#DumpResponse
func Dump(req, resp *string) Option {
return func(opts *Options) {
opts.DumpRequestOut = req
Expand Down
5 changes: 3 additions & 2 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package requests

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -32,8 +33,8 @@ func (r *Request) Text() string {
}

// newRequest creates a new HTTP request.
func newRequest(method, url string, opts *Options, body []byte) (*Request, error) {
r, err := http.NewRequestWithContext(opts.ctx, method, url, opts.Body)
func newRequest(ctx context.Context, method, url string, opts *Options, body []byte) (*Request, error) {
r, err := http.NewRequestWithContext(ctx, method, url, opts.Body)
if err != nil {
return nil, err
}
Expand Down
41 changes: 29 additions & 12 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,10 @@ func TestGetWithContext(t *testing.T) {
time.Sleep(100 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}))
defer testServer.Close()
ctx10ms, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
ctx200ms, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
type args struct {
url string
options []Option
url string
ctxTimeout time.Duration
options []Option
}
tests := []struct {
name string
Expand All @@ -143,26 +139,47 @@ func TestGetWithContext(t *testing.T) {
{
name: "with context 10ms",
args: args{
url: testServer.URL,
url: testServer.URL,
ctxTimeout: 10 * time.Millisecond,
},
wantErr: true,
},
{
name: "with context 200ms",
args: args{
url: testServer.URL,
ctxTimeout: 200 * time.Millisecond,
},
wantErr: false,
},
{
name: "with context 200ms and WithTimeout 10ms",
args: args{
url: testServer.URL,
ctxTimeout: 200 * time.Millisecond,
options: []Option{
Context(ctx10ms),
Timeout(10 * time.Millisecond),
},
},
wantErr: true,
},
{
name: "with context 200ms",
name: "with context 200ms and WithTimeout 150ms",
args: args{
url: testServer.URL,
url: testServer.URL,
ctxTimeout: 200 * time.Millisecond,
options: []Option{
Context(ctx200ms),
Timeout(150 * time.Millisecond),
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), tt.args.ctxTimeout)
defer cancel()
tt.args.options = append(tt.args.options, Context(ctx))
got, err := Get(tt.args.url, tt.args.options...)
if (err != nil) != tt.wantErr {
t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
Expand Down
Loading