Compare commits

...

5 Commits

Author SHA1 Message Date
a46c9d395a fix for multiple server registration
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-09 14:20:08 +03:00
Renovate Bot
d3c5a503c6 Update module github.com/unistack-org/micro/v3 to v3.2.20 2021-03-06 23:25:58 +00:00
Renovate Bot
be224692a4 Update module github.com/unistack-org/micro/v3 to v3.2.18 2021-03-06 19:32:16 +00:00
Renovate Bot
0da73b62ae Update module github.com/unistack-org/micro/v3 to v3.2.17 2021-03-05 17:17:15 +00:00
Renovate Bot
a30c2972fd Update module github.com/unistack-org/micro/v3 to v3.2.16 2021-03-04 12:21:58 +00:00
4 changed files with 74 additions and 44 deletions

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/unistack-org/micro-server-http/v3
go 1.13
require (
github.com/unistack-org/micro/v3 v3.2.15
github.com/unistack-org/micro/v3 v3.2.20
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
)

5
go.sum
View File

@@ -8,6 +8,11 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
github.com/unistack-org/micro/v3 v3.2.15 h1:9Wg6FAFVPUijAm5ZFF+y4oYEd8zd/Pp48QwmMrSs074=
github.com/unistack-org/micro/v3 v3.2.15/go.mod h1:y+fV+BPNK2IqGoLquRU396jTYifG0HCw3zxFfI4E0dc=
github.com/unistack-org/micro/v3 v3.2.16/go.mod h1:y+fV+BPNK2IqGoLquRU396jTYifG0HCw3zxFfI4E0dc=
github.com/unistack-org/micro/v3 v3.2.17/go.mod h1:y+fV+BPNK2IqGoLquRU396jTYifG0HCw3zxFfI4E0dc=
github.com/unistack-org/micro/v3 v3.2.18 h1:+EnZ6xJJzHINQr7c8nkwygkfy+qLssiKd1hktgEzHL4=
github.com/unistack-org/micro/v3 v3.2.18/go.mod h1:y+fV+BPNK2IqGoLquRU396jTYifG0HCw3zxFfI4E0dc=
github.com/unistack-org/micro/v3 v3.2.20/go.mod h1:y+fV+BPNK2IqGoLquRU396jTYifG0HCw3zxFfI4E0dc=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -34,13 +34,13 @@ type patHandler struct {
}
type httpHandler struct {
name string
opts server.HandlerOptions
sopts server.Options
eps []*register.Endpoint
hd interface{}
handlers map[string][]patHandler
errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int)
name string
opts server.HandlerOptions
sopts server.Options
eps []*register.Endpoint
hd interface{}
handlers map[string][]patHandler
//errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int)
}
func (h *httpHandler) newCodec(ct string) (codec.Codec, error) {
@@ -66,14 +66,14 @@ func (h *httpHandler) Options() server.HandlerOptions {
return h.opts
}
func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := metadata.NewContext(r.Context(), nil)
defer r.Body.Close()
path := r.URL.Path
if !strings.HasPrefix(path, "/") {
h.errorHandler(ctx, h, w, r, fmt.Errorf("path must contains /"), http.StatusBadRequest)
h.errorHandler(ctx, nil, w, r, fmt.Errorf("path must contains /"), http.StatusBadRequest)
}
ct := DefaultContentType
@@ -83,7 +83,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
cf, err := h.newCodec(ct)
if err != nil {
h.errorHandler(ctx, h, w, r, err, http.StatusBadRequest)
h.errorHandler(ctx, nil, w, r, err, http.StatusBadRequest)
}
components := strings.Split(path[1:], "/")
@@ -91,7 +91,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var verb string
idx := strings.LastIndex(components[l-1], ":")
if idx == 0 {
h.errorHandler(ctx, h, w, r, fmt.Errorf("not found"), http.StatusNotFound)
h.errorHandler(ctx, nil, w, r, fmt.Errorf("not found"), http.StatusNotFound)
return
}
if idx > 0 {
@@ -102,19 +102,25 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
matches := make(map[string]interface{})
var match bool
var hldr patHandler
for _, hldr = range h.handlers[r.Method] {
mp, err := hldr.pat.Match(components, verb)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
var handler *httpHandler
for _, hpat := range h.handlers {
handlertmp := hpat.(*httpHandler)
for _, hldrtmp := range handlertmp.handlers[r.Method] {
mp, err := hldrtmp.pat.Match(components, verb)
if err == nil {
match = true
for k, v := range mp {
matches[k] = v
}
hldr = hldrtmp
handler = handlertmp
break
}
break
}
}
if !match {
h.errorHandler(ctx, h, w, r, fmt.Errorf("not matching route found"), http.StatusNotFound)
h.errorHandler(ctx, nil, w, r, fmt.Errorf("not matching route found"), http.StatusNotFound)
return
}
@@ -131,7 +137,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(r.URL.RawQuery) > 0 {
umd, err := rflutil.URLMap(r.URL.RawQuery)
if err != nil {
h.errorHandler(ctx, h, w, r, err, http.StatusBadRequest)
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
}
for k, v := range umd {
matches[k] = v
@@ -161,24 +167,24 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var returnValues []reflect.Value
if err = cf.ReadBody(r.Body, argv.Interface()); err != nil && err != io.EOF {
h.errorHandler(ctx, h, w, r, err, http.StatusInternalServerError)
h.errorHandler(ctx, handler, w, r, err, http.StatusInternalServerError)
}
matches = rflutil.FlattenMap(matches)
if err = rflutil.MergeMap(argv.Interface(), matches); err != nil {
h.errorHandler(ctx, h, w, r, err, http.StatusBadRequest)
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
b, err := cf.Marshal(argv.Interface())
if err != nil {
h.errorHandler(ctx, h, w, r, err, http.StatusBadRequest)
h.errorHandler(ctx, handler, w, r, err, http.StatusBadRequest)
return
}
hr := &rpcRequest{
codec: cf,
service: h.sopts.Name,
service: handler.sopts.Name,
contentType: ct,
method: fmt.Sprintf("%s.%s", hldr.name, hldr.mtype.method.Name),
body: b,
@@ -206,8 +212,8 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
// wrap the handler func
for i := len(h.sopts.HdlrWrappers); i > 0; i-- {
fn = h.sopts.HdlrWrappers[i-1](fn)
for i := len(handler.sopts.HdlrWrappers); i > 0; i-- {
fn = handler.sopts.HdlrWrappers[i-1](fn)
}
if appErr := fn(ctx, hr, replyv.Interface()); appErr != nil {
@@ -223,8 +229,8 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else {
b, err = cf.Marshal(replyv.Interface())
}
if err != nil && h.sopts.Logger.V(logger.ErrorLevel) {
h.sopts.Logger.Errorf(h.sopts.Context, "handler err: %v", err)
if err != nil && handler.sopts.Logger.V(logger.ErrorLevel) {
handler.sopts.Logger.Errorf(handler.sopts.Context, "handler err: %v", err)
return
}
@@ -238,7 +244,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if scode != 0 {
w.WriteHeader(scode)
} else {
h.sopts.Logger.Warn(h.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.Write(b)
}

47
http.go
View File

@@ -4,7 +4,6 @@ package http
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
@@ -26,6 +25,7 @@ import (
type httpServer struct {
sync.RWMutex
opts server.Options
handlers map[string]server.Handler
hd server.Handler
exit chan chan error
subscribers map[*httpSubscriber][]broker.Subscriber
@@ -33,6 +33,8 @@ type httpServer struct {
registered bool
// register service instance
rsvc *register.Service
errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int)
}
func (h *httpServer) newCodec(ct string) (codec.Codec, error) {
@@ -54,13 +56,30 @@ func (h *httpServer) Init(opts ...server.Option) error {
for _, o := range opts {
o(&h.opts)
}
h.errorHandler = DefaultErrorHandler
if fn, ok := h.opts.Context.Value(errorHandlerKey{}).(func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int)); ok && fn != nil {
h.errorHandler = fn
}
h.handlers = make(map[string]server.Handler)
h.Unlock()
return nil
}
func (h *httpServer) Handle(handler server.Handler) error {
h.Lock()
h.hd = handler
if hdlr, ok := handler.(*httpHandler); ok {
if h.handlers == nil {
h.handlers = make(map[string]server.Handler)
}
if _, ok := hdlr.hd.(http.Handler); ok {
h.hd = handler
} else {
h.handlers[handler.Name()] = handler
}
} else {
h.hd = handler
}
h.Unlock()
return nil
}
@@ -86,10 +105,6 @@ func (h *httpServer) NewHandler(handler interface{}, opts ...server.HandlerOptio
sopts: h.opts,
}
hdlr.errorHandler = DefaultErrorHandler
if fn, ok := options.Context.Value(errorHandlerKey{}).(func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int)); ok && fn != nil {
hdlr.errorHandler = fn
}
tp := reflect.TypeOf(handler)
/*
@@ -184,8 +199,11 @@ func (h *httpServer) Subscribe(sb server.Subscriber) error {
}
func (h *httpServer) Register() error {
var eps []*register.Endpoint
h.RLock()
eps := h.hd.Endpoints()
for _, hdlr := range h.handlers {
eps = append(eps, hdlr.Endpoints()...)
}
rsvc := h.rsvc
config := h.opts
h.RUnlock()
@@ -322,7 +340,6 @@ func (h *httpServer) Deregister() error {
func (h *httpServer) Start() error {
h.RLock()
config := h.opts
hd := h.hd
h.RUnlock()
// micro: config.Transport.Listen(config.Address)
@@ -357,14 +374,16 @@ func (h *httpServer) Start() error {
h.opts.Address = ts.Addr().String()
h.Unlock()
handler, ok := hd.Handler().(http.Handler)
if !ok {
handler, ok = hd.(http.Handler)
var handler http.Handler
if h.hd == nil {
handler = h
} else if hdlr, ok := h.hd.Handler().(http.Handler); ok {
handler = hdlr
}
if !ok {
return errors.New("Server required http.Handler")
}
//if !ok {
// return errors.New("Server required http.Handler")
//}
if err := config.Broker.Connect(h.opts.Context); err != nil {
return err