parent
a215521821
commit
6c661c9d72
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
|
40
handler.go
40
handler.go
@ -9,7 +9,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"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/logger"
|
"github.com/unistack-org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"github.com/unistack-org/micro/v3/metadata"
|
||||||
@ -22,7 +21,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
DefaultErrorHandler = func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int) {
|
DefaultErrorHandler = func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int) {
|
||||||
w.WriteHeader(status)
|
w.WriteHeader(status)
|
||||||
w.Write([]byte(err.Error()))
|
if _, cerr := w.Write([]byte(err.Error())); cerr != nil {
|
||||||
|
logger.DefaultLogger.Errorf(ctx, "write failed: %v", cerr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DefaultContentType = "application/json"
|
DefaultContentType = "application/json"
|
||||||
)
|
)
|
||||||
@ -44,20 +45,6 @@ type httpHandler struct {
|
|||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpHandler) newCodec(ct string) (codec.Codec, error) {
|
|
||||||
h.RLock()
|
|
||||||
defer h.RUnlock()
|
|
||||||
|
|
||||||
if idx := strings.IndexRune(ct, ';'); idx >= 0 {
|
|
||||||
ct = ct[:idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
if cf, ok := h.sopts.Codecs[ct]; ok {
|
|
||||||
return cf, nil
|
|
||||||
}
|
|
||||||
return nil, codec.ErrUnknownContentType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *httpHandler) Name() string {
|
func (h *httpHandler) Name() string {
|
||||||
return h.name
|
return h.name
|
||||||
}
|
}
|
||||||
@ -75,7 +62,6 @@ func (h *httpHandler) Options() server.HandlerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
for exp, ph := range h.pathHandlers {
|
for exp, ph := range h.pathHandlers {
|
||||||
if exp.MatchString(r.URL.String()) {
|
if exp.MatchString(r.URL.String()) {
|
||||||
ph(w, r)
|
ph(w, r)
|
||||||
@ -95,7 +81,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := metadata.NewContext(r.Context(), nil)
|
ctx := metadata.NewIncomingContext(r.Context(), nil)
|
||||||
|
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
@ -132,8 +118,8 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, hpat := range h.handlers {
|
for _, hpat := range h.handlers {
|
||||||
handlertmp := hpat.(*httpHandler)
|
handlertmp := hpat.(*httpHandler)
|
||||||
for _, hldrtmp := range handlertmp.handlers[r.Method] {
|
for _, hldrtmp := range handlertmp.handlers[r.Method] {
|
||||||
mp, err := hldrtmp.pat.Match(components, verb)
|
mp, merr := hldrtmp.pat.Match(components, verb)
|
||||||
if err == nil {
|
if merr == nil {
|
||||||
match = true
|
match = true
|
||||||
for k, v := range mp {
|
for k, v := range mp {
|
||||||
matches[k] = v
|
matches[k] = v
|
||||||
@ -161,9 +147,9 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// get fields from url values
|
// get fields from url values
|
||||||
if len(r.URL.RawQuery) > 0 {
|
if len(r.URL.RawQuery) > 0 {
|
||||||
umd, err := rflutil.URLMap(r.URL.RawQuery)
|
umd, cerr := rflutil.URLMap(r.URL.RawQuery)
|
||||||
if err != nil {
|
if cerr != nil {
|
||||||
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
|
h.errorHandler(ctx, handler, w, r, cerr, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for k, v := range umd {
|
for k, v := range umd {
|
||||||
@ -190,7 +176,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
replyv = reflect.New(hldr.mtype.ReplyType.Elem())
|
replyv = reflect.New(hldr.mtype.ReplyType.Elem())
|
||||||
|
|
||||||
function := hldr.mtype.method.Func
|
function := hldr.mtype.method.Func
|
||||||
//function := hldr.rcvr
|
// function := hldr.rcvr
|
||||||
var returnValues []reflect.Value
|
var returnValues []reflect.Value
|
||||||
|
|
||||||
if err = cf.ReadBody(r.Body, argv.Interface()); err != nil && err != io.EOF {
|
if err = cf.ReadBody(r.Body, argv.Interface()); err != nil && err != io.EOF {
|
||||||
@ -281,8 +267,10 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if scode != 0 {
|
if scode != 0 {
|
||||||
w.WriteHeader(scode)
|
w.WriteHeader(scode)
|
||||||
} else {
|
} else {
|
||||||
//handler.sopts.Logger.Warn(handler.sopts.Context, "response code not set in handler via SetRspCode(ctx, http.StatusXXX)")
|
// handler.sopts.Logger.Warn(handler.sopts.Context, "response code not set in handler via SetRspCode(ctx, http.StatusXXX)")
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
}
|
}
|
||||||
w.Write(b)
|
if _, cerr := w.Write(b); cerr != nil {
|
||||||
|
logger.DefaultLogger.Errorf(ctx, "write failed: %v", cerr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
34
http.go
34
http.go
@ -126,19 +126,23 @@ func (h *httpServer) Init(opts ...server.Option) error {
|
|||||||
|
|
||||||
func (h *httpServer) Handle(handler server.Handler) error {
|
func (h *httpServer) Handle(handler server.Handler) error {
|
||||||
h.Lock()
|
h.Lock()
|
||||||
if hdlr, ok := handler.(*httpHandler); ok {
|
defer h.Unlock()
|
||||||
|
hdlr, ok := handler.(*httpHandler)
|
||||||
|
if !ok {
|
||||||
|
h.hd = handler
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := hdlr.hd.(http.Handler); ok {
|
if _, ok := hdlr.hd.(http.Handler); ok {
|
||||||
h.hd = handler
|
h.hd = handler
|
||||||
} else {
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if h.handlers == nil {
|
if h.handlers == nil {
|
||||||
h.handlers = make(map[string]server.Handler)
|
h.handlers = make(map[string]server.Handler)
|
||||||
}
|
}
|
||||||
h.handlers[handler.Name()] = handler
|
h.handlers[handler.Name()] = handler
|
||||||
}
|
|
||||||
} else {
|
|
||||||
h.hd = handler
|
|
||||||
}
|
|
||||||
h.Unlock()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +283,7 @@ func (h *httpServer) Register() error {
|
|||||||
service.Endpoints = eps
|
service.Endpoints = eps
|
||||||
|
|
||||||
h.Lock()
|
h.Lock()
|
||||||
var subscriberList []*httpSubscriber
|
subscriberList := make([]*httpSubscriber, 0, len(h.subscribers))
|
||||||
for e := range h.subscribers {
|
for e := range h.subscribers {
|
||||||
// Only advertise non internal subscribers
|
// Only advertise non internal subscribers
|
||||||
subscriberList = append(subscriberList, e)
|
subscriberList = append(subscriberList, e)
|
||||||
@ -430,6 +434,7 @@ func (h *httpServer) Start() error {
|
|||||||
var handler http.Handler
|
var handler http.Handler
|
||||||
var srvFunc func(net.Listener) error
|
var srvFunc func(net.Listener) error
|
||||||
|
|
||||||
|
// nolint: nestif
|
||||||
if h.opts.Context != nil {
|
if h.opts.Context != nil {
|
||||||
if hs, ok := h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil {
|
if hs, ok := h.opts.Context.Value(serverKey{}).(*http.Server); ok && hs != nil {
|
||||||
if hs.Handler == nil && h.hd != nil {
|
if hs.Handler == nil && h.hd != nil {
|
||||||
@ -485,9 +490,17 @@ func (h *httpServer) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if srvFunc != nil {
|
if srvFunc != nil {
|
||||||
go srvFunc(ts)
|
go func() {
|
||||||
|
if cerr := srvFunc(ts); cerr != nil {
|
||||||
|
h.opts.Logger.Error(h.opts.Context, cerr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
} else {
|
} else {
|
||||||
go http.Serve(ts, fn)
|
go func() {
|
||||||
|
if cerr := http.Serve(ts, fn); cerr != nil {
|
||||||
|
h.opts.Logger.Error(h.opts.Context, cerr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -511,6 +524,7 @@ func (h *httpServer) Start() error {
|
|||||||
registered := h.registered
|
registered := h.registered
|
||||||
h.RUnlock()
|
h.RUnlock()
|
||||||
rerr := config.RegisterCheck(h.opts.Context)
|
rerr := config.RegisterCheck(h.opts.Context)
|
||||||
|
// nolint: nestif
|
||||||
if rerr != nil && registered {
|
if rerr != nil && registered {
|
||||||
if config.Logger.V(logger.ErrorLevel) {
|
if config.Logger.V(logger.ErrorLevel) {
|
||||||
config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s, deregister it", config.Name, config.Id, rerr)
|
config.Logger.Errorf(config.Context, "Server %s-%s register check error: %s, deregister it", config.Name, config.Id, rerr)
|
||||||
|
28
options.go
28
options.go
@ -8,11 +8,6 @@ import (
|
|||||||
"github.com/unistack-org/micro/v3/server"
|
"github.com/unistack-org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rspCodeKey struct{}
|
|
||||||
type rspCodeVal struct {
|
|
||||||
code int
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetError pass error to caller
|
// SetError pass error to caller
|
||||||
func SetError(err interface{}) error {
|
func SetError(err interface{}) error {
|
||||||
return &Error{err: err}
|
return &Error{err: err}
|
||||||
@ -28,6 +23,13 @@ func (err *Error) Error() string {
|
|||||||
return fmt.Sprintf("%v", err.err)
|
return fmt.Sprintf("%v", err.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
rspCodeKey struct{}
|
||||||
|
rspCodeVal struct {
|
||||||
|
code int
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// SetRspCode saves response code in context, must be used by handler to specify http code
|
// SetRspCode saves response code in context, must be used by handler to specify http code
|
||||||
func SetRspCode(ctx context.Context, code int) {
|
func SetRspCode(ctx context.Context, code int) {
|
||||||
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
|
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
|
||||||
@ -65,10 +67,12 @@ func ErrorHandler(fn func(ctx context.Context, s server.Handler, w http.Response
|
|||||||
return server.SetOption(errorHandlerKey{}, fn)
|
return server.SetOption(errorHandlerKey{}, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathHandlerKey struct{}
|
type (
|
||||||
type pathHandlerVal struct {
|
pathHandlerKey struct{}
|
||||||
|
pathHandlerVal struct {
|
||||||
h map[string]http.HandlerFunc
|
h map[string]http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// PathHandler specifies http handler for path regexp
|
// PathHandler specifies http handler for path regexp
|
||||||
func PathHandler(path string, h http.HandlerFunc) server.Option {
|
func PathHandler(path string, h http.HandlerFunc) server.Option {
|
||||||
@ -85,10 +89,12 @@ func PathHandler(path string, h http.HandlerFunc) server.Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type contentTypeHandlerKey struct{}
|
type (
|
||||||
type contentTypeHandlerVal struct {
|
contentTypeHandlerKey struct{}
|
||||||
|
contentTypeHandlerVal struct {
|
||||||
h map[string]http.HandlerFunc
|
h map[string]http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// ContentTypeHandler specifies http handler for Content-Type
|
// ContentTypeHandler specifies http handler for Content-Type
|
||||||
func ContentTypeHandler(ct string, h http.HandlerFunc) server.Option {
|
func ContentTypeHandler(ct string, h http.HandlerFunc) server.Option {
|
||||||
|
@ -5,6 +5,12 @@ import (
|
|||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"github.com/unistack-org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"github.com/unistack-org/micro/v3/metadata"
|
||||||
|
"github.com/unistack-org/micro/v3/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ server.Request = &rpcRequest{}
|
||||||
|
_ server.Message = &rpcMessage{}
|
||||||
)
|
)
|
||||||
|
|
||||||
type rpcRequest struct {
|
type rpcRequest struct {
|
||||||
@ -16,7 +22,6 @@ type rpcRequest struct {
|
|||||||
endpoint string
|
endpoint string
|
||||||
contentType string
|
contentType string
|
||||||
service string
|
service string
|
||||||
target string
|
|
||||||
body []byte
|
body []byte
|
||||||
stream bool
|
stream bool
|
||||||
}
|
}
|
||||||
@ -43,7 +48,7 @@ func (r *rpcRequest) Method() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcRequest) Endpoint() string {
|
func (r *rpcRequest) Endpoint() string {
|
||||||
return r.method
|
return r.endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rpcRequest) Codec() codec.Codec {
|
func (r *rpcRequest) Codec() codec.Codec {
|
||||||
|
@ -62,15 +62,14 @@ func prepareEndpoint(method reflect.Method) (*methodType, error) {
|
|||||||
return nil, fmt.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
|
return nil, fmt.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
|
||||||
}
|
}
|
||||||
|
|
||||||
if stream {
|
switch stream {
|
||||||
|
case true:
|
||||||
// check stream type
|
// check stream type
|
||||||
streamType := reflect.TypeOf((*server.Stream)(nil)).Elem()
|
streamType := reflect.TypeOf((*server.Stream)(nil)).Elem()
|
||||||
if !argType.Implements(streamType) {
|
if !argType.Implements(streamType) {
|
||||||
return nil, fmt.Errorf("%v argument does not implement Streamer interface: %v", mname, argType)
|
return nil, fmt.Errorf("%v argument does not implement Streamer interface: %v", mname, argType)
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
// if not stream check the replyType
|
|
||||||
|
|
||||||
// First arg need not be a pointer.
|
// First arg need not be a pointer.
|
||||||
if !isExportedOrBuiltinType(argType) {
|
if !isExportedOrBuiltinType(argType) {
|
||||||
return nil, fmt.Errorf("%v argument type not exported: %v", mname, argType)
|
return nil, fmt.Errorf("%v argument type not exported: %v", mname, argType)
|
||||||
|
@ -14,10 +14,6 @@ import (
|
|||||||
"github.com/unistack-org/micro/v3/server"
|
"github.com/unistack-org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
subSig = "func(context.Context, interface{}) error"
|
|
||||||
)
|
|
||||||
|
|
||||||
var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
|
var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
|
||||||
type handler struct {
|
type handler struct {
|
||||||
@ -116,7 +112,7 @@ func (s *httpServer) createSubHandler(sb *httpSubscriber, opts server.Options) b
|
|||||||
|
|
||||||
hdr := metadata.Copy(msg.Header)
|
hdr := metadata.Copy(msg.Header)
|
||||||
delete(hdr, "Content-Type")
|
delete(hdr, "Content-Type")
|
||||||
ctx := metadata.NewContext(context.Background(), hdr)
|
ctx := metadata.NewIncomingContext(context.Background(), hdr)
|
||||||
|
|
||||||
results := make(chan error, len(sb.handlers))
|
results := make(chan error, len(sb.handlers))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user