107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
package servlet
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
crp "git.loafle.net/commons/rpc-go/protocol"
|
|
crr "git.loafle.net/commons/rpc-go/registry"
|
|
"git.loafle.net/commons/server-go"
|
|
csw "git.loafle.net/commons/server-go/web"
|
|
cswf "git.loafle.net/commons/server-go/web/fasthttp"
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
type MethodMapping struct {
|
|
Method string
|
|
ParamKeys []string
|
|
}
|
|
|
|
type RESTServlet struct {
|
|
cswf.Servlets
|
|
|
|
ServerCodec crp.ServerCodec
|
|
RPCInvoker crr.RPCInvoker
|
|
|
|
MethodMapping map[string]MethodMapping
|
|
}
|
|
|
|
func (s *RESTServlet) Handle(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error {
|
|
method := string(ctx.Method())
|
|
|
|
switch method {
|
|
case "GET":
|
|
return s.HandleGet(servletCtx, ctx)
|
|
case "POST":
|
|
return s.HandlePost(servletCtx, ctx)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *RESTServlet) HandleGet(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error {
|
|
path := string(ctx.Path())
|
|
if nil == s.MethodMapping {
|
|
return csw.NewError(fasthttp.StatusNotFound, fmt.Errorf("Not Found for %s", path))
|
|
}
|
|
mapping, ok := s.MethodMapping[path]
|
|
if !ok {
|
|
return csw.NewError(fasthttp.StatusNotFound, fmt.Errorf("Not Found for %s", path))
|
|
}
|
|
|
|
method := mapping.Method
|
|
params := make([]string, 0)
|
|
if nil != mapping.ParamKeys && 0 < len(mapping.ParamKeys) {
|
|
qargs := ctx.QueryArgs()
|
|
if nil == qargs {
|
|
return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter is not valied"))
|
|
}
|
|
|
|
for _, k := range mapping.ParamKeys {
|
|
buf := qargs.Peek(k)
|
|
if nil == buf {
|
|
return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter for %s is not valied", k))
|
|
}
|
|
params = append(params, string(buf))
|
|
}
|
|
}
|
|
|
|
reqCodec, err := s.ServerCodec.NewRequestWithString(method, params, nil)
|
|
if nil != err {
|
|
return csw.NewError(fasthttp.StatusBadRequest, err)
|
|
}
|
|
|
|
reply, err := s.RPCInvoker.Invoke(reqCodec, servletCtx, ctx)
|
|
|
|
buf, err := reqCodec.NewResponseWithString(reply.(string), err)
|
|
if nil != err {
|
|
return csw.NewError(fasthttp.StatusInternalServerError, err)
|
|
}
|
|
|
|
ctx.SetBody(buf)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *RESTServlet) HandlePost(servletCtx server.ServletCtx, ctx *fasthttp.RequestCtx) *csw.Error {
|
|
buf := ctx.PostBody()
|
|
if nil == buf {
|
|
return csw.NewError(fasthttp.StatusBadRequest, fmt.Errorf("Parameter is not valied"))
|
|
}
|
|
|
|
reqCodec, err := s.ServerCodec.NewRequest(buf)
|
|
if nil != err {
|
|
return csw.NewError(fasthttp.StatusBadRequest, err)
|
|
}
|
|
|
|
reply, err := s.RPCInvoker.Invoke(reqCodec, servletCtx, ctx)
|
|
|
|
buf, err = reqCodec.NewResponseWithString(reply.(string), err)
|
|
if nil != err {
|
|
return csw.NewError(fasthttp.StatusInternalServerError, err)
|
|
}
|
|
|
|
ctx.SetBody(buf)
|
|
|
|
return nil
|
|
}
|