13
									
								
								.github/stale.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.github/stale.sh
									
									
									
									
										vendored
									
									
								
							@@ -1,13 +0,0 @@
 | 
				
			|||||||
#!/bin/bash -ex
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export PATH=$PATH:$(pwd)/bin
 | 
					 | 
				
			||||||
export GO111MODULE=on
 | 
					 | 
				
			||||||
export GOBIN=$(pwd)/bin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#go get github.com/rvflash/goup@v0.4.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#goup -v ./...
 | 
					 | 
				
			||||||
#go get github.com/psampaz/go-mod-outdated@v0.6.0
 | 
					 | 
				
			||||||
go list -u -m -mod=mod -json all | go-mod-outdated -update -direct -ci || true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#go list -u -m -json all | go-mod-outdated -update
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -34,10 +34,9 @@ jobs:
 | 
				
			|||||||
        uses: actions/checkout@v2
 | 
					        uses: actions/checkout@v2
 | 
				
			||||||
      - name: lint
 | 
					      - name: lint
 | 
				
			||||||
        uses: golangci/golangci-lint-action@v2
 | 
					        uses: golangci/golangci-lint-action@v2
 | 
				
			||||||
        continue-on-error: true
 | 
					 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
 | 
					          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
 | 
				
			||||||
          version: v1.30
 | 
					          version: v1.39
 | 
				
			||||||
          # Optional: working directory, useful for monorepos
 | 
					          # Optional: working directory, useful for monorepos
 | 
				
			||||||
          # working-directory: somedir
 | 
					          # working-directory: somedir
 | 
				
			||||||
          # Optional: golangci-lint command line arguments.
 | 
					          # Optional: golangci-lint command line arguments.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								.github/workflows/pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/pr.yml
									
									
									
									
										vendored
									
									
								
							@@ -34,10 +34,9 @@ jobs:
 | 
				
			|||||||
        uses: actions/checkout@v2
 | 
					        uses: actions/checkout@v2
 | 
				
			||||||
      - name: lint
 | 
					      - name: lint
 | 
				
			||||||
        uses: golangci/golangci-lint-action@v2
 | 
					        uses: golangci/golangci-lint-action@v2
 | 
				
			||||||
        continue-on-error: true
 | 
					 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
 | 
					          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
 | 
				
			||||||
          version: v1.30
 | 
					          version: v1.39
 | 
				
			||||||
          # Optional: working directory, useful for monorepos
 | 
					          # Optional: working directory, useful for monorepos
 | 
				
			||||||
          # working-directory: somedir
 | 
					          # working-directory: somedir
 | 
				
			||||||
          # Optional: golangci-lint command line arguments.
 | 
					          # Optional: golangci-lint command line arguments.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								.golangci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								.golangci.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					run:
 | 
				
			||||||
 | 
					  concurrency: 4
 | 
				
			||||||
 | 
					  deadline: 5m
 | 
				
			||||||
 | 
					  issues-exit-code: 1
 | 
				
			||||||
 | 
					  tests: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					linters-settings:
 | 
				
			||||||
 | 
					  govet:
 | 
				
			||||||
 | 
					    check-shadowing: true
 | 
				
			||||||
 | 
					    enable:
 | 
				
			||||||
 | 
					      - fieldalignment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					linters:
 | 
				
			||||||
 | 
					  enable:
 | 
				
			||||||
 | 
					    - govet
 | 
				
			||||||
 | 
					    - deadcode
 | 
				
			||||||
 | 
					    - errcheck
 | 
				
			||||||
 | 
					    - govet
 | 
				
			||||||
 | 
					    - ineffassign
 | 
				
			||||||
 | 
					    - staticcheck
 | 
				
			||||||
 | 
					    - structcheck
 | 
				
			||||||
 | 
					    - typecheck
 | 
				
			||||||
 | 
					    - unused
 | 
				
			||||||
 | 
					    - varcheck
 | 
				
			||||||
 | 
					    - bodyclose
 | 
				
			||||||
 | 
					    - gci
 | 
				
			||||||
 | 
					    - goconst
 | 
				
			||||||
 | 
					    - gocritic
 | 
				
			||||||
 | 
					    - gosimple
 | 
				
			||||||
 | 
					    - gofmt
 | 
				
			||||||
 | 
					    - gofumpt
 | 
				
			||||||
 | 
					    - goimports
 | 
				
			||||||
 | 
					    - golint
 | 
				
			||||||
 | 
					    - gosec
 | 
				
			||||||
 | 
					    - makezero
 | 
				
			||||||
 | 
					    - misspell
 | 
				
			||||||
 | 
					    - nakedret
 | 
				
			||||||
 | 
					    - nestif
 | 
				
			||||||
 | 
					    - nilerr
 | 
				
			||||||
 | 
					    - noctx
 | 
				
			||||||
 | 
					    - prealloc
 | 
				
			||||||
 | 
					    - unconvert
 | 
				
			||||||
 | 
					    - unparam
 | 
				
			||||||
 | 
					  disable-all: false
 | 
				
			||||||
							
								
								
									
										56
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								http.go
									
									
									
									
									
								
							@@ -20,21 +20,19 @@ import (
 | 
				
			|||||||
	"github.com/unistack-org/micro/v3/codec"
 | 
						"github.com/unistack-org/micro/v3/codec"
 | 
				
			||||||
	"github.com/unistack-org/micro/v3/errors"
 | 
						"github.com/unistack-org/micro/v3/errors"
 | 
				
			||||||
	"github.com/unistack-org/micro/v3/metadata"
 | 
						"github.com/unistack-org/micro/v3/metadata"
 | 
				
			||||||
	"github.com/unistack-org/micro/v3/router"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var DefaultContentType = "application/json"
 | 
				
			||||||
	DefaultContentType = "application/json"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
func filterLabel(r []router.Route) []router.Route {
 | 
					func filterLabel(r []router.Route) []router.Route {
 | 
				
			||||||
	//				selector.FilterLabel("protocol", "http")
 | 
						//				selector.FilterLabel("protocol", "http")
 | 
				
			||||||
	return r
 | 
						return r
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type httpClient struct {
 | 
					type httpClient struct {
 | 
				
			||||||
	opts    client.Options
 | 
						opts    client.Options
 | 
				
			||||||
	dialer  *net.Dialer
 | 
					 | 
				
			||||||
	httpcli *http.Client
 | 
						httpcli *http.Client
 | 
				
			||||||
	init    bool
 | 
						init    bool
 | 
				
			||||||
	sync.RWMutex
 | 
						sync.RWMutex
 | 
				
			||||||
@@ -46,6 +44,7 @@ func newRequest(addr string, req client.Request, ct string, cf codec.Codec, msg
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var tags []string
 | 
						var tags []string
 | 
				
			||||||
	var scheme string
 | 
						var scheme string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u, err := url.Parse(addr)
 | 
						u, err := url.Parse(addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		hreq.URL = &url.URL{
 | 
							hreq.URL = &url.URL{
 | 
				
			||||||
@@ -55,7 +54,10 @@ func newRequest(addr string, req client.Request, ct string, cf codec.Codec, msg
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		hreq.Host = addr
 | 
							hreq.Host = addr
 | 
				
			||||||
		scheme = "http"
 | 
							scheme = "http"
 | 
				
			||||||
	} else {
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// nolint: nestif
 | 
				
			||||||
 | 
						if scheme == "" {
 | 
				
			||||||
		ep := req.Endpoint()
 | 
							ep := req.Endpoint()
 | 
				
			||||||
		if opts.Context != nil {
 | 
							if opts.Context != nil {
 | 
				
			||||||
			if m, ok := opts.Context.Value(methodKey{}).(string); ok {
 | 
								if m, ok := opts.Context.Value(methodKey{}).(string); ok {
 | 
				
			||||||
@@ -70,7 +72,6 @@ func newRequest(addr string, req client.Request, ct string, cf codec.Codec, msg
 | 
				
			|||||||
			if t, ok := opts.Context.Value(structTagsKey{}).([]string); ok && len(t) > 0 {
 | 
								if t, ok := opts.Context.Value(structTagsKey{}).([]string); ok && len(t) > 0 {
 | 
				
			||||||
				tags = t
 | 
									tags = t
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		hreq.URL, err = u.Parse(ep)
 | 
							hreq.URL, err = u.Parse(ep)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -147,26 +148,20 @@ func (h *httpClient) call(ctx context.Context, addr string, req client.Request,
 | 
				
			|||||||
	hrsp, err := h.httpcli.Do(hreq.WithContext(ctx))
 | 
						hrsp, err := h.httpcli.Do(hreq.WithContext(ctx))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		switch err := err.(type) {
 | 
							switch err := err.(type) {
 | 
				
			||||||
		case net.Error:
 | 
					 | 
				
			||||||
			if err.Timeout() {
 | 
					 | 
				
			||||||
				return errors.Timeout("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case *url.Error:
 | 
							case *url.Error:
 | 
				
			||||||
			if err, ok := err.Err.(net.Error); ok && err.Timeout() {
 | 
								if err, ok := err.Err.(net.Error); ok && err.Timeout() {
 | 
				
			||||||
				return errors.Timeout("go.micro.client", err.Error())
 | 
									return errors.Timeout("go.micro.client", err.Error())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case net.Error:
 | 
				
			||||||
 | 
								if err.Timeout() {
 | 
				
			||||||
 | 
									return errors.Timeout("go.micro.client", err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return errors.InternalServerError("go.micro.client", err.Error())
 | 
							return errors.InternalServerError("go.micro.client", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer hrsp.Body.Close()
 | 
						defer hrsp.Body.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ct == "application/x-www-form-urlencoded" {
 | 
					 | 
				
			||||||
		cf, err = h.newCodec(DefaultContentType)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return h.parseRsp(ctx, hrsp, rsp, opts)
 | 
						return h.parseRsp(ctx, hrsp, rsp, opts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -198,11 +193,6 @@ func (h *httpClient) stream(ctx context.Context, addr string, req client.Request
 | 
				
			|||||||
		return nil, errors.InternalServerError("go.micro.client", err.Error())
 | 
							return nil, errors.InternalServerError("go.micro.client", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dialAddr := addr
 | 
					 | 
				
			||||||
	u, err := url.Parse(dialAddr)
 | 
					 | 
				
			||||||
	if err == nil && u.Scheme != "" && u.Host != "" {
 | 
					 | 
				
			||||||
		dialAddr = u.Host
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cc, err := (h.httpcli.Transport).(*http.Transport).DialContext(ctx, "tcp", addr)
 | 
						cc, err := (h.httpcli.Transport).(*http.Transport).DialContext(ctx, "tcp", addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error dialing: %v", err))
 | 
							return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error dialing: %v", err))
 | 
				
			||||||
@@ -296,7 +286,7 @@ func (h *httpClient) Call(ctx context.Context, req client.Request, rsp interface
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// got a deadline so no need to setup context
 | 
							// got a deadline so no need to setup context
 | 
				
			||||||
		// but we need to set the timeout we pass along
 | 
							// but we need to set the timeout we pass along
 | 
				
			||||||
		opt := client.WithRequestTimeout(d.Sub(time.Now()))
 | 
							opt := client.WithRequestTimeout(time.Until(d))
 | 
				
			||||||
		opt(&callOpts)
 | 
							opt(&callOpts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -423,7 +413,7 @@ func (h *httpClient) Stream(ctx context.Context, req client.Request, opts ...cli
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// got a deadline so no need to setup context
 | 
							// got a deadline so no need to setup context
 | 
				
			||||||
		// but we need to set the timeout we pass along
 | 
							// but we need to set the timeout we pass along
 | 
				
			||||||
		opt := client.WithRequestTimeout(d.Sub(time.Now()))
 | 
							opt := client.WithRequestTimeout(time.Until(d))
 | 
				
			||||||
		opt(&callOpts)
 | 
							opt(&callOpts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -476,9 +466,9 @@ func (h *httpClient) Stream(ctx context.Context, req client.Request, opts ...cli
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	call := func(i int) (client.Stream, error) {
 | 
						call := func(i int) (client.Stream, error) {
 | 
				
			||||||
		// call backoff first. Someone may want an initial start delay
 | 
							// call backoff first. Someone may want an initial start delay
 | 
				
			||||||
		t, err := callOpts.Backoff(ctx, req, i)
 | 
							t, cerr := callOpts.Backoff(ctx, req, i)
 | 
				
			||||||
		if err != nil {
 | 
							if cerr != nil {
 | 
				
			||||||
			return nil, errors.InternalServerError("go.micro.client", err.Error())
 | 
								return nil, errors.InternalServerError("go.micro.client", cerr.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// only sleep if greater than 0
 | 
							// only sleep if greater than 0
 | 
				
			||||||
@@ -488,19 +478,19 @@ func (h *httpClient) Stream(ctx context.Context, req client.Request, opts ...cli
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		node := next()
 | 
							node := next()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stream, err := h.stream(ctx, node, req, callOpts)
 | 
							stream, cerr := h.stream(ctx, node, req, callOpts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// record the result of the call to inform future routing decisions
 | 
							// record the result of the call to inform future routing decisions
 | 
				
			||||||
		if verr := h.opts.Selector.Record(node, err); verr != nil {
 | 
							if verr := h.opts.Selector.Record(node, cerr); verr != nil {
 | 
				
			||||||
			return nil, verr
 | 
								return nil, verr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// try and transform the error to a go-micro error
 | 
							// try and transform the error to a go-micro error
 | 
				
			||||||
		if verr, ok := err.(*errors.Error); ok {
 | 
							if verr, ok := cerr.(*errors.Error); ok {
 | 
				
			||||||
			return nil, verr
 | 
								return nil, verr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return stream, err
 | 
							return stream, cerr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type response struct {
 | 
						type response struct {
 | 
				
			||||||
@@ -513,8 +503,8 @@ func (h *httpClient) Stream(ctx context.Context, req client.Request, opts ...cli
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for i := 0; i <= callOpts.Retries; i++ {
 | 
						for i := 0; i <= callOpts.Retries; i++ {
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			s, err := call(i)
 | 
								s, cerr := call(i)
 | 
				
			||||||
			ch <- response{s, err}
 | 
								ch <- response{s, cerr}
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,9 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type httpMessage struct {
 | 
					type httpMessage struct {
 | 
				
			||||||
 | 
						payload     interface{}
 | 
				
			||||||
	topic       string
 | 
						topic       string
 | 
				
			||||||
	contentType string
 | 
						contentType string
 | 
				
			||||||
	payload     interface{}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newHTTPMessage(topic string, payload interface{}, contentType string, opts ...client.MessageOption) client.Message {
 | 
					func newHTTPMessage(topic string, payload interface{}, contentType string, opts ...client.MessageOption) client.Message {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								options.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								options.go
									
									
									
									
									
								
							@@ -26,27 +26,28 @@ var (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type poolMaxStreams struct{}
 | 
					type poolMaxStreams struct{}
 | 
				
			||||||
type poolMaxIdle struct{}
 | 
					 | 
				
			||||||
type codecsKey struct{}
 | 
					 | 
				
			||||||
type tlsAuth struct{}
 | 
					 | 
				
			||||||
type maxRecvMsgSizeKey struct{}
 | 
					 | 
				
			||||||
type maxSendMsgSizeKey struct{}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PoolMaxStreams maximum streams on a connectioin
 | 
					// PoolMaxStreams maximum streams on a connectioin
 | 
				
			||||||
func PoolMaxStreams(n int) client.Option {
 | 
					func PoolMaxStreams(n int) client.Option {
 | 
				
			||||||
	return client.SetOption(poolMaxStreams{}, n)
 | 
						return client.SetOption(poolMaxStreams{}, n)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type poolMaxIdle struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PoolMaxIdle maximum idle conns of a pool
 | 
					// PoolMaxIdle maximum idle conns of a pool
 | 
				
			||||||
func PoolMaxIdle(d int) client.Option {
 | 
					func PoolMaxIdle(d int) client.Option {
 | 
				
			||||||
	return client.SetOption(poolMaxIdle{}, d)
 | 
						return client.SetOption(poolMaxIdle{}, d)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type maxRecvMsgSizeKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MaxRecvMsgSize set the maximum size of message that client can receive.
 | 
					// MaxRecvMsgSize set the maximum size of message that client can receive.
 | 
				
			||||||
func MaxRecvMsgSize(s int) client.Option {
 | 
					func MaxRecvMsgSize(s int) client.Option {
 | 
				
			||||||
	return client.SetOption(maxRecvMsgSizeKey{}, s)
 | 
						return client.SetOption(maxRecvMsgSizeKey{}, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type maxSendMsgSizeKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MaxSendMsgSize set the maximum size of message that client can send.
 | 
					// MaxSendMsgSize set the maximum size of message that client can send.
 | 
				
			||||||
func MaxSendMsgSize(s int) client.Option {
 | 
					func MaxSendMsgSize(s int) client.Option {
 | 
				
			||||||
	return client.SetOption(maxSendMsgSizeKey{}, s)
 | 
						return client.SetOption(maxSendMsgSizeKey{}, s)
 | 
				
			||||||
@@ -54,12 +55,14 @@ func MaxSendMsgSize(s int) client.Option {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type httpClientKey struct{}
 | 
					type httpClientKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nolint: golint
 | 
				
			||||||
func HTTPClient(c *http.Client) client.Option {
 | 
					func HTTPClient(c *http.Client) client.Option {
 | 
				
			||||||
	return client.SetOption(httpClientKey{}, c)
 | 
						return client.SetOption(httpClientKey{}, c)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type httpDialerKey struct{}
 | 
					type httpDialerKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nolint: golint
 | 
				
			||||||
func HTTPDialer(d *net.Dialer) client.Option {
 | 
					func HTTPDialer(d *net.Dialer) client.Option {
 | 
				
			||||||
	return client.SetOption(httpDialerKey{}, d)
 | 
						return client.SetOption(httpDialerKey{}, d)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								stream.go
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								stream.go
									
									
									
									
									
								
							@@ -16,24 +16,21 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Implements the streamer interface
 | 
					// Implements the streamer interface
 | 
				
			||||||
type httpStream struct {
 | 
					type httpStream struct {
 | 
				
			||||||
	sync.RWMutex
 | 
					 | 
				
			||||||
	address string
 | 
					 | 
				
			||||||
	opts    client.CallOptions
 | 
					 | 
				
			||||||
	ct      string
 | 
					 | 
				
			||||||
	cf      codec.Codec
 | 
					 | 
				
			||||||
	context context.Context
 | 
					 | 
				
			||||||
	header  http.Header
 | 
					 | 
				
			||||||
	seq     uint64
 | 
					 | 
				
			||||||
	closed  chan bool
 | 
					 | 
				
			||||||
	err     error
 | 
						err     error
 | 
				
			||||||
	conn    net.Conn
 | 
						conn    net.Conn
 | 
				
			||||||
	reader  *bufio.Reader
 | 
						cf      codec.Codec
 | 
				
			||||||
 | 
						context context.Context
 | 
				
			||||||
	request client.Request
 | 
						request client.Request
 | 
				
			||||||
 | 
						header  http.Header
 | 
				
			||||||
 | 
						closed  chan bool
 | 
				
			||||||
 | 
						reader  *bufio.Reader
 | 
				
			||||||
 | 
						address string
 | 
				
			||||||
 | 
						ct      string
 | 
				
			||||||
 | 
						opts    client.CallOptions
 | 
				
			||||||
 | 
						sync.RWMutex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var errShutdown = fmt.Errorf("connection is shut down")
 | 
				
			||||||
	errShutdown = fmt.Errorf("connection is shut down")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *httpStream) isClosed() bool {
 | 
					func (h *httpStream) isClosed() bool {
 | 
				
			||||||
	select {
 | 
						select {
 | 
				
			||||||
@@ -112,34 +109,39 @@ func (h *httpStream) Close() error {
 | 
				
			|||||||
func (h *httpStream) parseRsp(ctx context.Context, hrsp *http.Response, cf codec.Codec, rsp interface{}, opts client.CallOptions) error {
 | 
					func (h *httpStream) parseRsp(ctx context.Context, hrsp *http.Response, cf codec.Codec, rsp interface{}, opts client.CallOptions) error {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// fast path return
 | 
						select {
 | 
				
			||||||
	if hrsp.StatusCode == http.StatusNoContent {
 | 
						case <-ctx.Done():
 | 
				
			||||||
		return nil
 | 
							err = ctx.Err()
 | 
				
			||||||
	}
 | 
						default:
 | 
				
			||||||
 | 
							// fast path return
 | 
				
			||||||
	if hrsp.StatusCode < 400 {
 | 
							if hrsp.StatusCode == http.StatusNoContent {
 | 
				
			||||||
		if err = cf.ReadBody(hrsp.Body, rsp); err != nil {
 | 
								return nil
 | 
				
			||||||
			return errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	errmap, ok := opts.Context.Value(errorMapKey{}).(map[string]interface{})
 | 
							if hrsp.StatusCode < 400 {
 | 
				
			||||||
	if ok && errmap != nil {
 | 
								if err = cf.ReadBody(hrsp.Body, rsp); err != nil {
 | 
				
			||||||
		if err, ok = errmap[fmt.Sprintf("%d", hrsp.StatusCode)].(error); !ok {
 | 
									return errors.InternalServerError("go.micro.client", err.Error())
 | 
				
			||||||
			err, ok = errmap["default"].(error)
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		buf, err := io.ReadAll(hrsp.Body)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return errors.New("go.micro.client", string(buf), int32(hrsp.StatusCode))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cerr := cf.ReadBody(hrsp.Body, err); cerr != nil {
 | 
							errmap, ok := opts.Context.Value(errorMapKey{}).(map[string]interface{})
 | 
				
			||||||
		err = errors.InternalServerError("go.micro.client", cerr.Error())
 | 
							if ok && errmap != nil {
 | 
				
			||||||
 | 
								if err, ok = errmap[fmt.Sprintf("%d", hrsp.StatusCode)].(error); !ok {
 | 
				
			||||||
 | 
									err, ok = errmap["default"].(error)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !ok || err == nil {
 | 
				
			||||||
 | 
								buf, cerr := io.ReadAll(hrsp.Body)
 | 
				
			||||||
 | 
								if cerr != nil {
 | 
				
			||||||
 | 
									return errors.InternalServerError("go.micro.client", cerr.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return errors.New("go.micro.client", string(buf), int32(hrsp.StatusCode))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if cerr := cf.ReadBody(hrsp.Body, err); cerr != nil {
 | 
				
			||||||
 | 
								err = errors.InternalServerError("go.micro.client", cerr.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								util.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								util.go
									
									
									
									
									
								
							@@ -96,13 +96,15 @@ func newPathRequest(path string, method string, body string, msg interface{}, ta
 | 
				
			|||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// nolint: gocritic
 | 
				
			||||||
		if _, ok := fieldsmap[t.name]; ok {
 | 
							if _, ok := fieldsmap[t.name]; ok {
 | 
				
			||||||
			if val.Type().Kind() == reflect.Slice {
 | 
								switch val.Type().Kind() {
 | 
				
			||||||
 | 
								case reflect.Slice:
 | 
				
			||||||
				for idx := 0; idx < val.Len(); idx++ {
 | 
									for idx := 0; idx < val.Len(); idx++ {
 | 
				
			||||||
					values.Add(t.name, fmt.Sprintf("%v", val.Index(idx).Interface()))
 | 
										values.Add(t.name, fmt.Sprintf("%v", val.Index(idx).Interface()))
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				fieldsmapskip[t.name] = struct{}{}
 | 
									fieldsmapskip[t.name] = struct{}{}
 | 
				
			||||||
			} else {
 | 
								default:
 | 
				
			||||||
				fieldsmap[t.name] = fmt.Sprintf("%v", val.Interface())
 | 
									fieldsmap[t.name] = fmt.Sprintf("%v", val.Interface())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if (body == "*" || body == t.name) && method != http.MethodGet {
 | 
							} else if (body == "*" || body == t.name) && method != http.MethodGet {
 | 
				
			||||||
@@ -173,45 +175,52 @@ func newTemplate(path string) (util.Template, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *httpClient) parseRsp(ctx context.Context, hrsp *http.Response, rsp interface{}, opts client.CallOptions) error {
 | 
					func (h *httpClient) parseRsp(ctx context.Context, hrsp *http.Response, rsp interface{}, opts client.CallOptions) error {
 | 
				
			||||||
	// fast path return
 | 
						var err error
 | 
				
			||||||
	if hrsp.StatusCode == http.StatusNoContent {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ct := DefaultContentType
 | 
						select {
 | 
				
			||||||
 | 
						case <-ctx.Done():
 | 
				
			||||||
	if htype := hrsp.Header.Get("Content-Type"); htype != "" {
 | 
							err = ctx.Err()
 | 
				
			||||||
		ct = htype
 | 
						default:
 | 
				
			||||||
	}
 | 
							// fast path return
 | 
				
			||||||
 | 
							if hrsp.StatusCode == http.StatusNoContent {
 | 
				
			||||||
	cf, err := h.newCodec(ct)
 | 
								return nil
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if hrsp.StatusCode < 400 {
 | 
					 | 
				
			||||||
		if err := cf.ReadBody(hrsp.Body, rsp); err != nil {
 | 
					 | 
				
			||||||
			return errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	errmap, ok := opts.Context.Value(errorMapKey{}).(map[string]interface{})
 | 
							ct := DefaultContentType
 | 
				
			||||||
	if ok && errmap != nil {
 | 
					 | 
				
			||||||
		if err, ok = errmap[fmt.Sprintf("%d", hrsp.StatusCode)].(error); !ok {
 | 
					 | 
				
			||||||
			err, ok = errmap["default"].(error)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		buf, err := io.ReadAll(hrsp.Body)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			errors.InternalServerError("go.micro.client", err.Error())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return errors.New("go.micro.client", string(buf), int32(hrsp.StatusCode))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cerr := cf.ReadBody(hrsp.Body, err); cerr != nil {
 | 
							if htype := hrsp.Header.Get("Content-Type"); htype != "" {
 | 
				
			||||||
		err = errors.InternalServerError("go.micro.client", cerr.Error())
 | 
								ct = htype
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cf, cerr := h.newCodec(ct)
 | 
				
			||||||
 | 
							if cerr != nil {
 | 
				
			||||||
 | 
								return errors.InternalServerError("go.micro.client", cerr.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if hrsp.StatusCode < 400 {
 | 
				
			||||||
 | 
								if err = cf.ReadBody(hrsp.Body, rsp); err != nil {
 | 
				
			||||||
 | 
									return errors.InternalServerError("go.micro.client", err.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							errmap, ok := opts.Context.Value(errorMapKey{}).(map[string]interface{})
 | 
				
			||||||
 | 
							if ok && errmap != nil {
 | 
				
			||||||
 | 
								if err, ok = errmap[fmt.Sprintf("%d", hrsp.StatusCode)].(error); !ok {
 | 
				
			||||||
 | 
									err, ok = errmap["default"].(error)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !ok || err == nil {
 | 
				
			||||||
 | 
								buf, rerr := io.ReadAll(hrsp.Body)
 | 
				
			||||||
 | 
								if rerr != nil {
 | 
				
			||||||
 | 
									return errors.InternalServerError("go.micro.client", rerr.Error())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return errors.New("go.micro.client", string(buf), int32(hrsp.StatusCode))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if cerr := cf.ReadBody(hrsp.Body, err); cerr != nil {
 | 
				
			||||||
 | 
								err = errors.InternalServerError("go.micro.client", cerr.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,8 +18,8 @@ func TestNewPathRequest(t *testing.T) {
 | 
				
			|||||||
	type Message struct {
 | 
						type Message struct {
 | 
				
			||||||
		Name string `json:"name"`
 | 
							Name string `json:"name"`
 | 
				
			||||||
		Val1 string `protobuf:"bytes,1,opt,name=val1,proto3" json:"val1"`
 | 
							Val1 string `protobuf:"bytes,1,opt,name=val1,proto3" json:"val1"`
 | 
				
			||||||
		Val2 int64
 | 
					 | 
				
			||||||
		Val3 []string
 | 
							Val3 []string
 | 
				
			||||||
 | 
							Val2 int64
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	omsg := &Message{Name: "test_name", Val1: "test_val1", Val2: 100, Val3: []string{"slice"}}
 | 
						omsg := &Message{Name: "test_name", Val1: "test_val1", Val2: 100, Val3: []string{"slice"}}
 | 
				
			||||||
@@ -45,8 +45,8 @@ func TestNewPathVarRequest(t *testing.T) {
 | 
				
			|||||||
	type Message struct {
 | 
						type Message struct {
 | 
				
			||||||
		Name string `json:"name"`
 | 
							Name string `json:"name"`
 | 
				
			||||||
		Val1 string `protobuf:"bytes,1,opt,name=val1,proto3" json:"val1"`
 | 
							Val1 string `protobuf:"bytes,1,opt,name=val1,proto3" json:"val1"`
 | 
				
			||||||
		Val2 int64
 | 
					 | 
				
			||||||
		Val3 []string
 | 
							Val3 []string
 | 
				
			||||||
 | 
							Val2 int64
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	omsg := &Message{Name: "test_name", Val1: "test_val1", Val2: 100, Val3: []string{"slice"}}
 | 
						omsg := &Message{Name: "test_name", Val1: "test_val1", Val2: 100, Val3: []string{"slice"}}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user