2021-02-02 16:13:39 +03:00
|
|
|
package http
|
|
|
|
|
2021-02-07 13:27:28 +03:00
|
|
|
import (
|
|
|
|
"context"
|
2021-02-25 14:16:55 +03:00
|
|
|
"fmt"
|
2021-02-07 13:27:28 +03:00
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/unistack-org/micro/v3/server"
|
|
|
|
)
|
2021-02-02 16:13:39 +03:00
|
|
|
|
|
|
|
type rspCodeKey struct{}
|
|
|
|
type rspCodeVal struct {
|
|
|
|
code int
|
|
|
|
}
|
|
|
|
|
2021-03-01 20:23:22 +03:00
|
|
|
// SetError pass error to caller
|
2021-02-25 14:16:55 +03:00
|
|
|
func SetError(err interface{}) error {
|
|
|
|
return &Error{err: err}
|
|
|
|
}
|
|
|
|
|
2021-03-01 20:23:22 +03:00
|
|
|
// Error struct holds error
|
2021-02-25 14:16:55 +03:00
|
|
|
type Error struct {
|
|
|
|
err interface{}
|
|
|
|
}
|
|
|
|
|
2021-03-01 20:23:22 +03:00
|
|
|
// Error func for error interface
|
2021-02-25 14:16:55 +03:00
|
|
|
func (err *Error) Error() string {
|
|
|
|
return fmt.Sprintf("%v", err.err)
|
|
|
|
}
|
|
|
|
|
2021-02-02 16:13:39 +03:00
|
|
|
// SetRspCode saves response code in context, must be used by handler to specify http code
|
|
|
|
func SetRspCode(ctx context.Context, code int) {
|
|
|
|
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
|
|
|
|
rsp.code = code
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetRspCode used internally by generated http server handler
|
|
|
|
func GetRspCode(ctx context.Context) int {
|
|
|
|
var code int
|
|
|
|
if rsp, ok := ctx.Value(rspCodeKey{}).(*rspCodeVal); ok {
|
|
|
|
code = rsp.code
|
|
|
|
}
|
|
|
|
return code
|
|
|
|
}
|
2021-02-07 13:27:28 +03:00
|
|
|
|
|
|
|
type middlewareKey struct{}
|
|
|
|
|
2021-03-01 20:23:22 +03:00
|
|
|
// Middleware passes http middlewares
|
2021-02-07 13:27:28 +03:00
|
|
|
func Middleware(mw ...func(http.Handler) http.Handler) server.Option {
|
|
|
|
return server.SetOption(middlewareKey{}, mw)
|
|
|
|
}
|
2021-02-07 19:03:38 +03:00
|
|
|
|
|
|
|
type serverKey struct{}
|
|
|
|
|
2021-03-01 20:23:22 +03:00
|
|
|
// Server provide ability to pass *http.Server
|
2021-02-07 19:03:38 +03:00
|
|
|
func Server(hs *http.Server) server.Option {
|
|
|
|
return server.SetOption(serverKey{}, hs)
|
|
|
|
}
|
2021-03-01 20:23:22 +03:00
|
|
|
|
|
|
|
type errorHandlerKey struct{}
|
|
|
|
|
|
|
|
// ErrorHandler specifies handler for errors
|
|
|
|
func ErrorHandler(fn func(ctx context.Context, s server.Handler, w http.ResponseWriter, r *http.Request, err error, status int)) server.Option {
|
|
|
|
return server.SetOption(errorHandlerKey{}, fn)
|
|
|
|
}
|
2021-03-24 15:22:20 +03:00
|
|
|
|
2021-04-13 11:32:56 +03:00
|
|
|
type pathHandlerKey struct{}
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|