add httpclient add options

This commit is contained in:
holooooo 2021-04-20 17:52:33 +08:00
parent 29849ddb36
commit 575bf62fd3
8 changed files with 716 additions and 80 deletions

View File

@ -1,33 +0,0 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"net/http"
"net/url"
"time"
)
type ClientOption func(client *Client) error
// client设置
func WithTimeout(connectTimeout, readWriteTimeout time.Duration) ClientOption
func WithEnableCookie(enable bool) ClientOption
func WithUserAgent(userAgent string) ClientOption
func WithCookie(cookie *http.Cookie) ClientOption
func WithTransport(transport http.RoundTripper) ClientOption
func WithProxy(proxy func(*http.Request) (*url.URL, error)) ClientOption
func WithCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) ClientOption
func WithAccept(accept string) ClientOption

View File

@ -1,25 +0,0 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import "github.com/beego/beego/v2/client/httplib"
type BeegoHttpRequestOption func(request *httplib.BeegoHTTPRequest) error
// Req设置
func WithTokenFactory(tokenFactory func() (string, error)) BeegoHttpRequestOption
func WithBasicAuth(basicAuth func() (string, error)) BeegoHttpRequestOption
func WithFilters(fcs ...httplib.FilterChain) BeegoHttpRequestOption
func WithContentType(contentType string) BeegoHttpRequestOption

View File

@ -0,0 +1,175 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httplib
import (
"crypto/tls"
"net/http"
"net/url"
"time"
)
type ClientOption func(client *Client) error
type BeegoHttpRequestOption func(request *BeegoHTTPRequest) error
// WithEnableCookie will enable cookie in all subsequent request
func WithEnableCookie(enable bool) ClientOption {
return func(client *Client) error {
client.Setting.EnableCookie = enable
return nil
}
}
// WithEnableCookie will adds UA in all subsequent request
func WithUserAgent(userAgent string) ClientOption {
return func(client *Client) error {
client.Setting.UserAgent = userAgent
return nil
}
}
// WithTLSClientConfig will adds tls config in all subsequent request
func WithTLSClientConfig(config *tls.Config) ClientOption {
return func(client *Client) error {
client.Setting.TLSClientConfig = config
return nil
}
}
// WithTransport will set transport field in all subsequent request
func WithTransport(transport http.RoundTripper) ClientOption {
return func(client *Client) error {
client.Setting.Transport = transport
return nil
}
}
// WithProxy will set http proxy field in all subsequent request
func WithProxy(proxy func(*http.Request) (*url.URL, error)) ClientOption {
return func(client *Client) error {
client.Setting.Proxy = proxy
return nil
}
}
// WithCheckRedirect will specifies the policy for handling redirects in all subsequent request
func WithCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) ClientOption {
return func(client *Client) error {
client.Setting.CheckRedirect = redirect
return nil
}
}
// WithHTTPSetting can replace beegoHTTPSeting
func WithHTTPSetting(setting BeegoHTTPSettings) ClientOption {
return func(client *Client) error {
client.Setting = &setting
return nil
}
}
// WithEnableGzip will enable gzip in all subsequent request
func WithEnableGzip(enable bool) ClientOption {
return func(client *Client) error {
client.Setting.Gzip = enable
return nil
}
}
// BeegoHttpRequestOption
// WithTimeout sets connect time out and read-write time out for BeegoRequest.
func WithTimeout(connectTimeout, readWriteTimeout time.Duration) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.SetTimeout(connectTimeout, readWriteTimeout)
return nil
}
}
// WithHeader adds header item string in request.
func WithHeader(key, value string) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.Header(key, value)
return nil
}
}
// WithCookie adds a cookie to the request.
func WithCookie(cookie *http.Cookie) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.Header("Cookie", cookie.String())
return nil
}
}
// Withtokenfactory adds a custom function to set Authorization
func WithTokenFactory(tokenFactory func() (string, error)) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
t, err := tokenFactory()
if err != nil {
return err
}
request.Header("Authorization", t)
return nil
}
}
// WithBasicAuth adds a custom function to set basic auth
func WithBasicAuth(basicAuth func() (string, string, error)) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
username, password, err := basicAuth()
if err != nil {
return err
}
request.SetBasicAuth(username, password)
return nil
}
}
// WithFilters will use the filter as the invocation filters
func WithFilters(fcs ...FilterChain) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.SetFilters(fcs...)
return nil
}
}
// WithContentType adds ContentType in header
func WithContentType(contentType string) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.Header("Content-Type", contentType)
return nil
}
}
// WithParam adds query param in to request.
func WithParam(key, value string) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.Param(key, value)
return nil
}
}
// WithRetry set retry times and delay for the request
// default is 0 (never retry)
// -1 retry indefinitely (forever)
// Other numbers specify the exact retry amount
func WithRetry(times int, delay time.Duration) BeegoHttpRequestOption {
return func(request *BeegoHTTPRequest) error {
request.Retries(times)
request.RetryDelay(delay)
return nil
}
}

View File

@ -0,0 +1,250 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httplib
import (
"errors"
"net"
"net/http"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestOption_WithEnableCookie(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/",
WithEnableCookie(true))
if err != nil {
t.Fatal(err)
}
v := "smallfish"
var str *string
err = client.Get(&str, "/cookies/set?k1="+v)
if err != nil {
t.Fatal(err)
}
t.Log(*str)
err = client.Get(&str, "/cookies")
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, v)
if n == -1 {
t.Fatal(v + " not found in cookie")
}
}
func TestOption_WithUserAgent(t *testing.T) {
v := "beego"
client, err := NewClient("test", "http://httpbin.org/",
WithUserAgent(v))
if err != nil {
t.Fatal(err)
}
var str *string
err = client.Get(&str, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, v)
if n == -1 {
t.Fatal(v + " not found in user-agent")
}
}
func TestOption_WithCheckRedirect(t *testing.T) {
client, err := NewClient("test", "https://goolnk.com/33BD2j",
WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
return errors.New("Redirect triggered")
}))
if err != nil {
t.Fatal(err)
}
err = client.Get(nil, "")
assert.NotNil(t, err)
}
func TestOption_WithHTTPSetting(t *testing.T) {
v := "beego"
var setting BeegoHTTPSettings
setting.EnableCookie = true
setting.UserAgent = v
setting.Transport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 50,
IdleConnTimeout: 90 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
setting.ReadWriteTimeout = 5 * time.Second
client, err := NewClient("test", "http://httpbin.org/",
WithHTTPSetting(setting))
if err != nil {
t.Fatal(err)
}
var str *string
err = client.Get(&str, "/get")
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, v)
if n == -1 {
t.Fatal(v + " not found in user-agent")
}
}
func TestOption_WithHeader(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
client.CommonOpts = append(client.CommonOpts, WithHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"))
var str *string
err = client.Get(&str, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, "Mozilla/5.0")
if n == -1 {
t.Fatal("Mozilla/5.0 not found in user-agent")
}
}
func TestOption_WithTokenFactory(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
client.CommonOpts = append(client.CommonOpts,
WithTokenFactory(func() (string, error) {
return "testauth", nil
}))
var str *string
err = client.Get(&str, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, "testauth")
if n == -1 {
t.Fatal("Auth is not set in request")
}
}
func TestOption_WithBasicAuth(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var str *string
err = client.Get(&str, "/basic-auth/user/passwd",
WithBasicAuth(func() (string, string, error) {
return "user", "passwd", nil
}))
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, "authenticated")
if n == -1 {
t.Fatal("authenticated not found in response")
}
}
func TestOption_WithContentType(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
v := "application/json"
var str *string
err = client.Get(&str, "/headers", WithContentType(v))
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, v)
if n == -1 {
t.Fatal(v + " not found in header")
}
}
func TestOption_WithParam(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
v := "smallfish"
var str *string
err = client.Get(&str, "/get", WithParam("username", v))
if err != nil {
t.Fatal(err)
}
t.Log(str)
n := strings.Index(*str, v)
if n == -1 {
t.Fatal(v + " not found in header")
}
}
func TestOption_WithRetry(t *testing.T) {
client, err := NewClient("test", "https://goolnk.com/33BD2j",
WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
return errors.New("Redirect triggered")
}))
if err != nil {
t.Fatal(err)
}
retryAmount := 1
retryDelay := 1400 * time.Millisecond
startTime := time.Now().UnixNano() / int64(time.Millisecond)
err = client.Get(nil, "", WithRetry(retryAmount, retryDelay))
assert.NotNil(t, err)
endTime := time.Now().UnixNano() / int64(time.Millisecond)
elapsedTime := endTime - startTime
delayedTime := int64(retryAmount) * retryDelay.Milliseconds()
if elapsedTime < delayedTime {
t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime)
}
}

View File

@ -12,26 +12,26 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package client package httplib
import ( import (
"net/http" "net/http"
"strings" "strings"
"github.com/beego/beego/v2/client/httplib"
"github.com/beego/beego/v2/core/berror" "github.com/beego/beego/v2/core/berror"
) )
// Client provides an HTTP client supporting chain call
type Client struct { type Client struct {
Name string Name string
Endpoint string Endpoint string
CommonOpts []BeegoHttpRequestOption CommonOpts []BeegoHttpRequestOption
Setting *httplib.BeegoHTTPSettings Setting *BeegoHTTPSettings
pointer *ResponsePointer pointer *responsePointer
} }
type ResponsePointer struct { type responsePointer struct {
response **http.Response response **http.Response
statusCode **int statusCode **int
header **http.Header header **http.Header
@ -39,12 +39,14 @@ type ResponsePointer struct {
contentLength **int64 contentLength **int64
} }
// NewClient // NewClient return a new http client
func NewClient(name string, endpoint string, opts ...ClientOption) (*Client, error) { func NewClient(name string, endpoint string, opts ...ClientOption) (*Client, error) {
res := &Client{ res := &Client{
Name: name, Name: name,
Endpoint: endpoint, Endpoint: endpoint,
} }
setting := GetDefaultSetting()
res.Setting = &setting
for _, o := range opts { for _, o := range opts {
err := o(res) err := o(res)
if err != nil { if err != nil {
@ -58,7 +60,7 @@ func NewClient(name string, endpoint string, opts ...ClientOption) (*Client, err
func (c *Client) Response(resp **http.Response) *Client { func (c *Client) Response(resp **http.Response) *Client {
if c.pointer == nil { if c.pointer == nil {
newC := *c newC := *c
newC.pointer = &ResponsePointer{ newC.pointer = &responsePointer{
response: resp, response: resp,
} }
return &newC return &newC
@ -71,7 +73,7 @@ func (c *Client) Response(resp **http.Response) *Client {
func (c *Client) StatusCode(code **int) *Client { func (c *Client) StatusCode(code **int) *Client {
if c.pointer == nil { if c.pointer == nil {
newC := *c newC := *c
newC.pointer = &ResponsePointer{ newC.pointer = &responsePointer{
statusCode: code, statusCode: code,
} }
return &newC return &newC
@ -84,7 +86,7 @@ func (c *Client) StatusCode(code **int) *Client {
func (c *Client) Headers(headers **http.Header) *Client { func (c *Client) Headers(headers **http.Header) *Client {
if c.pointer == nil { if c.pointer == nil {
newC := *c newC := *c
newC.pointer = &ResponsePointer{ newC.pointer = &responsePointer{
header: headers, header: headers,
} }
return &newC return &newC
@ -97,7 +99,7 @@ func (c *Client) Headers(headers **http.Header) *Client {
func (c *Client) HeaderValue(key string, value **string) *Client { func (c *Client) HeaderValue(key string, value **string) *Client {
if c.pointer == nil { if c.pointer == nil {
newC := *c newC := *c
newC.pointer = &ResponsePointer{ newC.pointer = &responsePointer{
headerValues: map[string]**string{ headerValues: map[string]**string{
key: value, key: value,
}, },
@ -120,7 +122,7 @@ func (c *Client) ContentType(contentType **string) *Client {
func (c *Client) ContentLength(contentLength **int64) *Client { func (c *Client) ContentLength(contentLength **int64) *Client {
if c.pointer == nil { if c.pointer == nil {
newC := *c newC := *c
newC.pointer = &ResponsePointer{ newC.pointer = &responsePointer{
contentLength: contentLength, contentLength: contentLength,
} }
return &newC return &newC
@ -155,19 +157,19 @@ func (c *Client) setPointers(resp *http.Response) {
} }
// initRequest will apply all the client setting, common option and request option // initRequest will apply all the client setting, common option and request option
func (c *Client) newRequest(method, path string, opts []BeegoHttpRequestOption) (*httplib.BeegoHTTPRequest, error) { func (c *Client) newRequest(method, path string, opts []BeegoHttpRequestOption) (*BeegoHTTPRequest, error) {
var req *httplib.BeegoHTTPRequest var req *BeegoHTTPRequest
switch method { switch method {
case http.MethodGet: case http.MethodGet:
req = httplib.Get(c.Endpoint + path) req = Get(c.Endpoint + path)
case http.MethodPost: case http.MethodPost:
req = httplib.Post(c.Endpoint + path) req = Post(c.Endpoint + path)
case http.MethodPut: case http.MethodPut:
req = httplib.Put(c.Endpoint + path) req = Put(c.Endpoint + path)
case http.MethodDelete: case http.MethodDelete:
req = httplib.Delete(c.Endpoint + path) req = Delete(c.Endpoint + path)
case http.MethodHead: case http.MethodHead:
req = httplib.Head(c.Endpoint + path) req = Head(c.Endpoint + path)
} }
req = req.Setting(*c.Setting) req = req.Setting(*c.Setting)
@ -187,7 +189,7 @@ func (c *Client) newRequest(method, path string, opts []BeegoHttpRequestOption)
} }
// handleResponse try to parse body to meaningful value // handleResponse try to parse body to meaningful value
func (c *Client) handleResponse(value interface{}, req *httplib.BeegoHTTPRequest) error { func (c *Client) handleResponse(value interface{}, req *BeegoHTTPRequest) error {
// send request // send request
resp, err := req.Response() resp, err := req.Response()
if err != nil { if err != nil {
@ -195,6 +197,10 @@ func (c *Client) handleResponse(value interface{}, req *httplib.BeegoHTTPRequest
} }
c.setPointers(resp) c.setPointers(resp)
if value == nil {
return nil
}
// handle basic type // handle basic type
switch v := value.(type) { switch v := value.(type) {
case **string: case **string:
@ -217,7 +223,7 @@ func (c *Client) handleResponse(value interface{}, req *httplib.BeegoHTTPRequest
switch strings.Split(resp.Header.Get("Content-Type"), ";")[0] { switch strings.Split(resp.Header.Get("Content-Type"), ";")[0] {
case "application/json": case "application/json":
return req.ToJSON(value) return req.ToJSON(value)
case "text/xml": case "text/xml", "application/xml":
return req.ToXML(value) return req.ToXML(value)
case "text/yaml", "application/x-yaml": case "text/yaml", "application/x-yaml":
return req.ToYAML(value) return req.ToYAML(value)
@ -235,7 +241,7 @@ func (c *Client) handleResponse(value interface{}, req *httplib.BeegoHTTPRequest
} }
// TODO add new error type about can't parse body // TODO add new error type about can't parse body
return berror.Error(httplib.UnsupportedBodyType, "unsupported body data") return berror.Error(UnsupportedBodyType, "unsupported body data")
} }
// Get Send a GET request and try to give its result value // Get Send a GET request and try to give its result value

View File

@ -0,0 +1,258 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httplib
import (
"encoding/xml"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewClient(t *testing.T) {
client, err := NewClient("test1", "http://beego.me", WithEnableCookie(true))
assert.NoError(t, err)
assert.NotNil(t, client)
assert.Equal(t, true, client.Setting.EnableCookie)
}
func TestClient_Response(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var resp *http.Response
err = client.Response(&resp).Get(nil, "status/203")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, 203, resp.StatusCode)
}
func TestClient_StatusCode(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var statusCode *int
err = client.StatusCode(&statusCode).Get(nil, "status/203")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, 203, *statusCode)
}
func TestClient_Headers(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var header *http.Header
err = client.Headers(&header).Get(nil, "bytes/123")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "123", header.Get("Content-Length"))
}
func TestClient_HeaderValue(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var val *string
err = client.Headers(nil).HeaderValue("Content-Length", &val).Get(nil, "bytes/123")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "123", *val)
}
func TestClient_ContentType(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var contentType *string
err = client.ContentType(&contentType).Get(nil, "bytes/123")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "application/octet-stream", *contentType)
}
func TestClient_ContentLength(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
var contentLength *int64
err = client.ContentLength(&contentLength).Get(nil, "bytes/123")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, int64(123), *contentLength)
}
type total struct {
Slideshow slideshow `json:"slideshow" yaml:"slideshow"`
}
type slideshow struct {
XMLName xml.Name `xml:"slideshow"`
Title string `json:"title" yaml:"title" xml:"title,attr"`
Author string `json:"author" yaml:"author" xml:"author,attr"`
Date string `json:"date" yaml:"date" xml:"date,attr"`
Slides []slide `json:"slides" yaml:"slides" xml:"slide"`
}
type slide struct {
XMLName xml.Name `xml:"slide"`
Title string `json:"title" yaml:"title" xml:"title"`
}
func TestClient_Get(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
// basic type
var s *string
err = client.Get(&s, "/base64/SFRUUEJJTiBpcyBhd2Vzb21l")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "HTTPBIN is awesome", *s)
var bytes *[]byte
err = client.Get(&bytes, "/base64/SFRUUEJJTiBpcyBhd2Vzb21l")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, []byte("HTTPBIN is awesome"), *bytes)
// json
var tp *total
err = client.Get(&tp, "/json")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "Sample Slide Show", tp.Slideshow.Title)
assert.Equal(t, 2, len(tp.Slideshow.Slides))
assert.Equal(t, "Overview", tp.Slideshow.Slides[1].Title)
// xml
var ssp *slideshow
err = client.Get(&ssp, "/base64/PD94bWwgPz48c2xpZGVzaG93CnRpdGxlPSJTYW1wbGUgU2xpZGUgU2hvdyIKZGF0ZT0iRGF0ZSBvZiBwdWJsaWNhdGlvbiIKYXV0aG9yPSJZb3VycyBUcnVseSI+PHNsaWRlIHR5cGU9ImFsbCI+PHRpdGxlPldha2UgdXAgdG8gV29uZGVyV2lkZ2V0cyE8L3RpdGxlPjwvc2xpZGU+PHNsaWRlIHR5cGU9ImFsbCI+PHRpdGxlPk92ZXJ2aWV3PC90aXRsZT48aXRlbT5XaHkgPGVtPldvbmRlcldpZGdldHM8L2VtPiBhcmUgZ3JlYXQ8L2l0ZW0+PGl0ZW0vPjxpdGVtPldobyA8ZW0+YnV5czwvZW0+IFdvbmRlcldpZGdldHM8L2l0ZW0+PC9zbGlkZT48L3NsaWRlc2hvdz4=")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "Sample Slide Show", ssp.Title)
assert.Equal(t, 2, len(ssp.Slides))
assert.Equal(t, "Overview", ssp.Slides[1].Title)
// yaml
tp = nil
err = client.Get(&tp, "/base64/c2xpZGVzaG93OgogIGF1dGhvcjogWW91cnMgVHJ1bHkKICBkYXRlOiBkYXRlIG9mIHB1YmxpY2F0aW9uCiAgc2xpZGVzOgogIC0gdGl0bGU6IFdha2UgdXAgdG8gV29uZGVyV2lkZ2V0cyEKICAgIHR5cGU6IGFsbAogIC0gaXRlbXM6CiAgICAtIFdoeSA8ZW0+V29uZGVyV2lkZ2V0czwvZW0+IGFyZSBncmVhdAogICAgLSBXaG8gPGVtPmJ1eXM8L2VtPiBXb25kZXJXaWRnZXRzCiAgICB0aXRsZTogT3ZlcnZpZXcKICAgIHR5cGU6IGFsbAogIHRpdGxlOiBTYW1wbGUgU2xpZGUgU2hvdw==")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "Sample Slide Show", tp.Slideshow.Title)
assert.Equal(t, 2, len(tp.Slideshow.Slides))
assert.Equal(t, "Overview", tp.Slideshow.Slides[1].Title)
}
func TestClient_Post(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org")
if err != nil {
t.Fatal(err)
}
var s *string
err = client.Get(&s, "/json")
if err != nil {
t.Fatal(err)
}
var resp *http.Response
err = client.Response(&resp).Post(&s, "/post", *s)
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, resp)
assert.Equal(t, http.MethodPost, resp.Request.Method)
}
func TestClient_Put(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org")
if err != nil {
t.Fatal(err)
}
var s *string
err = client.Get(&s, "/json")
if err != nil {
t.Fatal(err)
}
var resp *http.Response
err = client.Response(&resp).Put(&s, "/put", *s)
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, resp)
assert.Equal(t, http.MethodPut, resp.Request.Method)
}
func TestClient_Delete(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org")
if err != nil {
t.Fatal(err)
}
var resp *http.Response
err = client.Response(&resp).Delete(nil, "/delete")
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, resp)
assert.Equal(t, http.MethodDelete, resp.Request.Method)
}
func TestClient_Head(t *testing.T) {
client, err := NewClient("test", "http://beego.me")
if err != nil {
t.Fatal(err)
}
var resp *http.Response
err = client.Response(&resp).Head(nil, "")
if err != nil {
t.Fatal(err)
}
assert.NotNil(t, resp)
assert.Equal(t, http.MethodHead, resp.Request.Method)
}

View File

@ -39,7 +39,7 @@ func TestResponse(t *testing.T) {
} }
func TestDoRequest(t *testing.T) { func TestDoRequest(t *testing.T) {
req := Get("https://goolnk.com/33BD2j") req := Get("https://goolnk.com/")
retryAmount := 1 retryAmount := 1
req.Retries(1) req.Retries(1)
req.RetryDelay(1400 * time.Millisecond) req.RetryDelay(1400 * time.Millisecond)

View File

@ -55,6 +55,11 @@ func SetDefaultSetting(setting BeegoHTTPSettings) {
defaultSetting = setting defaultSetting = setting
} }
// SetDefaultSetting return current default setting
func GetDefaultSetting() BeegoHTTPSettings {
return defaultSetting
}
var defaultSetting = BeegoHTTPSettings{ var defaultSetting = BeegoHTTPSettings{
UserAgent: "beegoServer", UserAgent: "beegoServer",
ConnectTimeout: 60 * time.Second, ConnectTimeout: 60 * time.Second,