add path handler option
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
0eb3c0b452
commit
622a79bd06
14
handler.go
14
handler.go
@ -66,6 +66,14 @@ 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 {
|
||||||
|
if exp.MatchString(r.URL.String()) {
|
||||||
|
ph(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx := metadata.NewContext(r.Context(), nil)
|
ctx := metadata.NewContext(r.Context(), nil)
|
||||||
|
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
@ -76,9 +84,9 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ct := strings.Split(DefaultContentType, ";")[0]
|
ct := DefaultContentType
|
||||||
if htype := r.Header.Get("Content-Type"); htype != "" {
|
if htype := r.Header.Get("Content-Type"); htype != "" {
|
||||||
ct = strings.Split(htype, ";")[0]
|
ct = htype
|
||||||
}
|
}
|
||||||
|
|
||||||
var cf codec.Codec
|
var cf codec.Codec
|
||||||
@ -87,7 +95,7 @@ func (h *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
case "application/x-www-form-urlencoded":
|
case "application/x-www-form-urlencoded":
|
||||||
cf, err = h.newCodec(strings.Split(DefaultContentType, ";")[0])
|
cf, err = h.newCodec(strings.Split(DefaultContentType, ";")[0])
|
||||||
default:
|
default:
|
||||||
cf, err = h.newCodec(ct)
|
cf, err = h.newCodec(strings.Split(ct, ";")[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
19
http.go
19
http.go
@ -8,6 +8,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -35,6 +36,7 @@ type httpServer struct {
|
|||||||
rsvc *register.Service
|
rsvc *register.Service
|
||||||
init bool
|
init bool
|
||||||
errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int)
|
errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int)
|
||||||
|
pathHandlers map[*regexp.Regexp]http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpServer) newCodec(ct string) (codec.Codec, error) {
|
func (h *httpServer) newCodec(ct string) (codec.Codec, error) {
|
||||||
@ -57,6 +59,8 @@ func (h *httpServer) Init(opts ...server.Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.Lock()
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&h.opts)
|
o(&h.opts)
|
||||||
}
|
}
|
||||||
@ -66,8 +70,18 @@ func (h *httpServer) Init(opts ...server.Option) error {
|
|||||||
if h.handlers == nil {
|
if h.handlers == nil {
|
||||||
h.handlers = make(map[string]server.Handler)
|
h.handlers = make(map[string]server.Handler)
|
||||||
}
|
}
|
||||||
h.Unlock()
|
if h.pathHandlers == nil {
|
||||||
|
h.pathHandlers = make(map[*regexp.Regexp]http.HandlerFunc)
|
||||||
|
}
|
||||||
|
if phs, ok := h.opts.Context.Value(pathHandlerKey{}).(*pathHandlerVal); ok && phs.h != nil {
|
||||||
|
for pp, ph := range phs.h {
|
||||||
|
exp, err := regexp.Compile(pp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
h.pathHandlers[exp] = ph
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := h.opts.Register.Init(); err != nil {
|
if err := h.opts.Register.Init(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -554,5 +568,6 @@ func NewServer(opts ...server.Option) server.Server {
|
|||||||
exit: make(chan chan error),
|
exit: make(chan chan error),
|
||||||
subscribers: make(map[*httpSubscriber][]broker.Subscriber),
|
subscribers: make(map[*httpSubscriber][]broker.Subscriber),
|
||||||
errorHandler: DefaultErrorHandler,
|
errorHandler: DefaultErrorHandler,
|
||||||
|
pathHandlers: make(map[*regexp.Regexp]http.HandlerFunc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
options.go
21
options.go
@ -65,5 +65,22 @@ 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 pathHandlerKey struct{}
|
||||||
// PathHandler specifies http handler for path
|
type pathHandlerVal struct {
|
||||||
|
h map[string]http.HandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathHandler specifies http handler for path regexp
|
||||||
|
func PathHandler(path string, h http.HandlerFunc) server.Option {
|
||||||
|
return func(o *server.Options) {
|
||||||
|
if o.Context == nil {
|
||||||
|
o.Context = context.Background()
|
||||||
|
}
|
||||||
|
v, ok := o.Context.Value(pathHandlerKey{}).(*pathHandlerVal)
|
||||||
|
if !ok {
|
||||||
|
v = &pathHandlerVal{h: make(map[string]http.HandlerFunc)}
|
||||||
|
}
|
||||||
|
v.h[path] = h
|
||||||
|
o.Context = context.WithValue(o.Context, pathHandlerKey{}, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user