Skip to content

Commit

Permalink
Update xhttp XRequest,XResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
onanying committed Oct 12, 2023
1 parent 80f19fd commit e5aae9f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 56 deletions.
12 changes: 6 additions & 6 deletions src/xutil/xhttp/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ import (

type Log struct {
Duration time.Duration `json:"duration"`
Request *http.Request `json:"request"`
Response *Response `json:"response"`
Request *XRequest `json:"request"`
Response *XResponse `json:"response"`
Error error `json:"error"`
}

type DebugFunc func(l *Log)

func doDebug(opt *requestOptions, duration time.Duration, req *http.Request, resp *Response, err error) {
if opt.DebugFunc == nil {
func doDebug(opts *requestOptions, duration time.Duration, req *http.Request, resp *XResponse, err error) {
if opts.DebugFunc == nil {
return
}

l := &Log{
Duration: duration,
Request: req,
Request: newXRequest(req),
Response: resp,
Error: err,
}
opt.DebugFunc(l)
opts.DebugFunc(l)
}
40 changes: 20 additions & 20 deletions src/xutil/xhttp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ type requestOptions struct {
}

func mergeOptions(opts []RequestOption) *requestOptions {
opt := DefaultOptions // copy
cp := DefaultOptions // copy
for _, o := range opts {
o.apply(&opt)
o.apply(&cp)
}
return &opt
return &cp
}

type RequestOption interface {
Expand All @@ -52,50 +52,50 @@ func (fdo *funcRequestOption) apply(do *requestOptions) {
}

func WithHeader(header http.Header) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Header = header
return &funcRequestOption{func(opts *requestOptions) {
opts.Header = header
}}
}

func WithContentType(contentType string) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Header.Set("Content-Type", contentType)
return &funcRequestOption{func(opts *requestOptions) {
opts.Header.Set("Content-Type", contentType)
}}
}

func WithTimeout(timeout time.Duration) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Timeout = timeout
return &funcRequestOption{func(opts *requestOptions) {
opts.Timeout = timeout
}}
}

func WithBody(body Body) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Body = body
return &funcRequestOption{func(opts *requestOptions) {
opts.Body = body
}}
}

func WithBodyBytes(body []byte) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Body = body
return &funcRequestOption{func(opts *requestOptions) {
opts.Body = body
}}
}

func WithBodyString(body string) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.Body = xconv.StringToBytes(body)
return &funcRequestOption{func(opts *requestOptions) {
opts.Body = xconv.StringToBytes(body)
}}
}

func WithDebugFunc(f DebugFunc) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.DebugFunc = f
return &funcRequestOption{func(opts *requestOptions) {
opts.DebugFunc = f
}}
}

func WithRetry(f RetryIfFunc, opts ...retry.Option) RequestOption {
return &funcRequestOption{func(opt *requestOptions) {
opt.RetryIfFunc = f
opt.RetryOptions = opts
return &funcRequestOption{func(o *requestOptions) {
o.RetryIfFunc = f
o.RetryOptions = opts
}}
}
67 changes: 44 additions & 23 deletions src/xutil/xhttp/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import (
"time"
)

type Response struct {
type XRequest struct {
*http.Request
Body Body
}

type XResponse struct {
*http.Response
Body Body
}
Expand All @@ -20,11 +25,27 @@ func (t Body) String() string {
return xconv.BytesToString(t)
}

func newResponse(r *http.Response) *Response {
func newXRequest(r *http.Request) *XRequest {
if r == nil {
return nil
}
resp := &XRequest{
Request: r,
}
b, err := io.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
return resp
}
resp.Body = b
return resp
}

func newXResponse(r *http.Response) *XResponse {
if r == nil {
return nil
}
resp := &Response{
resp := &XResponse{
Response: r,
}
b, err := io.ReadAll(r.Body)
Expand All @@ -36,51 +57,51 @@ func newResponse(r *http.Response) *Response {
return resp
}

func Request(method string, u string, opts ...RequestOption) (*Response, error) {
opt := mergeOptions(opts)
func Request(method string, u string, opts ...RequestOption) (*XResponse, error) {
o := mergeOptions(opts)
URL, err := url.Parse(u)
if err != nil {
return nil, err
}
req := &http.Request{
Method: method,
URL: URL,
Header: opt.Header,
Header: o.Header,
}
if opt.Body != nil {
req.Body = io.NopCloser(strings.NewReader(opt.Body.String()))
if o.Body != nil {
req.Body = io.NopCloser(strings.NewReader(o.Body.String()))
}

if opt.RetryOptions != nil {
return doRetry(opt, func() (*Response, error) {
return do(opt, req)
if o.RetryOptions != nil {
return doRetry(o, func() (*XResponse, error) {
return do(o, req)
})
}
return do(opt, req)
return do(o, req)
}

func Do(req *http.Request, opts ...RequestOption) (*Response, error) {
opt := mergeOptions(opts)
func Do(req *http.Request, opts ...RequestOption) (*XResponse, error) {
o := mergeOptions(opts)

if opt.RetryOptions != nil {
return doRetry(opt, func() (*Response, error) {
return do(opt, req)
if o.RetryOptions != nil {
return doRetry(o, func() (*XResponse, error) {
return do(o, req)
})
}
return do(opt, req)
return do(o, req)
}

func do(opt *requestOptions, req *http.Request) (*Response, error) {
func do(opts *requestOptions, req *http.Request) (*XResponse, error) {
cli := http.Client{
Timeout: opt.Timeout,
Timeout: opts.Timeout,
}
startTime := time.Now()
r, err := cli.Do(req)
if err != nil {
doDebug(opt, time.Now().Sub(startTime), req, nil, err)
doDebug(opts, time.Now().Sub(startTime), req, nil, err)
return nil, err
}
resp := newResponse(r)
doDebug(opt, time.Now().Sub(startTime), req, resp, nil)
resp := newXResponse(r)
doDebug(opts, time.Now().Sub(startTime), req, resp, nil)
return resp, nil
}
2 changes: 1 addition & 1 deletion src/xutil/xhttp/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestDebugAndRetry(t *testing.T) {
}

url := "https://aaaaa.com/"
retryIf := func(resp *xhttp.Response, err error) error {
retryIf := func(resp *xhttp.XResponse, err error) error {
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions src/xutil/xhttp/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import (
"github.com/avast/retry-go"
)

type RetryIfFunc func(*Response, error) error
type RetryIfFunc func(*XResponse, error) error

func doRetry(opt *requestOptions, f func() (*Response, error)) (*Response, error) {
var resp *Response
func doRetry(opts *requestOptions, f func() (*XResponse, error)) (*XResponse, error) {
var resp *XResponse
var err error
err = retry.Do(
func() error {
resp, err = f()
if opt.RetryIfFunc != nil {
return opt.RetryIfFunc(resp, err)
if opts.RetryIfFunc != nil {
return opts.RetryIfFunc(resp, err)
}
if err != nil {
return err
}
return nil
},
opt.RetryOptions...,
opts.RetryOptions...,
)
if err != nil {
return nil, err
Expand Down

0 comments on commit e5aae9f

Please sign in to comment.