diff --git a/CHANGELOG.md b/CHANGELOG.md index 93aa31f1..e177a51f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ - [upgrade redisgo to v1.8.8](https://github.com/beego/beego/pull/4872) - [fix prometheus CVE-2022-21698](https://github.com/beego/beego/pull/4878) - [upgrade to Go 1.18](https://github.com/beego/beego/pull/4896) - +- [Support NewBeegoRequestWithCtx in httplib](https://github.com/beego/beego/pull/4895) + # v2.0.2 See v2.0.2-beta.1 - [fix bug: etcd should use etcd as adapter name](https://github.com/beego/beego/pull/4845) diff --git a/client/httplib/error_code.go b/client/httplib/error_code.go index 177419ad..f87041e4 100644 --- a/client/httplib/error_code.go +++ b/client/httplib/error_code.go @@ -51,6 +51,10 @@ Sometimes you got JSON document and you want to make it as request body. So you If you do this, you got this code. Instead, you should call Header to set Content-type and call Body to set body data. `) +var InvalidURLOrMethod = berror.DefineCode(4001007, moduleName, "InvalidURLOrMethod", ` +You pass invalid url or method to httplib module. Please check the url and method, be careful about special characters. +`) + // start with 5 -------------------------------------------------------------------------- var CreateFormFileFailed = berror.DefineCode(5001001, moduleName, "CreateFormFileFailed", ` diff --git a/client/httplib/httplib.go b/client/httplib/httplib.go index 24cc5dd1..147f595b 100644 --- a/client/httplib/httplib.go +++ b/client/httplib/httplib.go @@ -67,26 +67,23 @@ var doRequestFilter = func(ctx context.Context, req *BeegoHTTPRequest) (*http.Re // I think if we don't return error // users are hard to check whether we create Beego request successfully func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest { - var resp http.Response - u, err := url.Parse(rawurl) + return NewBeegoRequestWithCtx(context.Background(), rawurl, method) +} + +// NewBeegoRequestWithCtx returns a new BeegoHTTPRequest given a method, URL +func NewBeegoRequestWithCtx(ctx context.Context, rawurl, method string) *BeegoHTTPRequest { + req, err := http.NewRequestWithContext(ctx, method, rawurl, nil) if err != nil { - logs.Error("%+v", berror.Wrapf(err, InvalidUrl, "invalid raw url: %s", rawurl)) - } - req := http.Request{ - URL: u, - Method: method, - Header: make(http.Header), - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, + logs.Error("%+v", berror.Wrapf(err, InvalidURLOrMethod, "invalid raw url or method: %s %s", rawurl, method)) } + return &BeegoHTTPRequest{ url: rawurl, - req: &req, + req: req, params: map[string][]string{}, files: map[string]string{}, setting: defaultSetting, - resp: &resp, + resp: &http.Response{}, } } @@ -409,7 +406,7 @@ func (b *BeegoHTTPRequest) handleFiles() { b.Header("Transfer-Encoding", "chunked") } -func (b *BeegoHTTPRequest) handleFileToBody(bodyWriter *multipart.Writer, formname string, filename string) { +func (*BeegoHTTPRequest) handleFileToBody(bodyWriter *multipart.Writer, formname string, filename string) { fileWriter, err := bodyWriter.CreateFormFile(formname, filename) const errFmt = "Httplib: %+v" if err != nil { @@ -445,9 +442,16 @@ func (b *BeegoHTTPRequest) getResponse() (*http.Response, error) { // DoRequest executes client.Do func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) { - return b.DoRequestWithCtx(context.Background()) + root := doRequestFilter + if len(b.setting.FilterChains) > 0 { + for i := len(b.setting.FilterChains) - 1; i >= 0; i-- { + root = b.setting.FilterChains[i](root) + } + } + return root(b.req.Context(), b) } +// Deprecated: please use NewBeegoRequestWithContext func (b *BeegoHTTPRequest) DoRequestWithCtx(ctx context.Context) (resp *http.Response, err error) { root := doRequestFilter if len(b.setting.FilterChains) > 0 { @@ -458,7 +462,7 @@ func (b *BeegoHTTPRequest) DoRequestWithCtx(ctx context.Context) (resp *http.Res return root(ctx, b) } -func (b *BeegoHTTPRequest) doRequest(ctx context.Context) (*http.Response, error) { +func (b *BeegoHTTPRequest) doRequest(_ context.Context) (*http.Response, error) { paramBody := b.buildParamBody() b.buildURL(paramBody) diff --git a/client/httplib/httplib_test.go b/client/httplib/httplib_test.go index 34624853..217351b2 100644 --- a/client/httplib/httplib_test.go +++ b/client/httplib/httplib_test.go @@ -350,6 +350,20 @@ func TestNewBeegoRequest(t *testing.T) { assert.NotNil(t, req) } +func TestNewBeegoRequestWithCtx(t *testing.T) { + req := NewBeegoRequestWithCtx(context.Background(), "http://beego.vip", "GET") + assert.NotNil(t, req) + assert.Equal(t, "GET", req.req.Method) + + // bad url but still get request + req = NewBeegoRequestWithCtx(context.Background(), "httpa\ta://beego.vip", "GET") + assert.NotNil(t, req) + + // bad method but still get request + req = NewBeegoRequestWithCtx(context.Background(), "http://beego.vip", "G\tET") + assert.NotNil(t, req) +} + func TestBeegoHTTPRequestSetProtocolVersion(t *testing.T) { req := NewBeegoRequest("http://beego.vip", "GET") assert.Equal(t, 1, req.req.ProtoMajor)