|
|
|
|
|
|
|
|
|
package gofiber |
|
|
|
import ( |
|
"errors" |
|
"io" |
|
"net/http" |
|
"net/url" |
|
"strings" |
|
|
|
"github.com/GoAdminGroup/go-admin/adapter" |
|
"github.com/GoAdminGroup/go-admin/context" |
|
"github.com/GoAdminGroup/go-admin/engine" |
|
"github.com/GoAdminGroup/go-admin/modules/config" |
|
"github.com/GoAdminGroup/go-admin/plugins" |
|
"github.com/GoAdminGroup/go-admin/plugins/admin/models" |
|
"github.com/GoAdminGroup/go-admin/plugins/admin/modules/constant" |
|
"github.com/GoAdminGroup/go-admin/template/types" |
|
"github.com/gofiber/fiber/v2" |
|
"github.com/valyala/fasthttp" |
|
) |
|
|
|
|
|
type Gofiber struct { |
|
adapter.BaseAdapter |
|
ctx *fiber.Ctx |
|
app *fiber.App |
|
} |
|
|
|
func init() { |
|
engine.Register(new(Gofiber)) |
|
} |
|
|
|
|
|
func (gof *Gofiber) User(ctx interface{}) (models.UserModel, bool) { |
|
return gof.GetUser(ctx, gof) |
|
} |
|
|
|
|
|
func (gof *Gofiber) Use(app interface{}, plugs []plugins.Plugin) error { |
|
return gof.GetUse(app, plugs, gof) |
|
} |
|
|
|
|
|
func (gof *Gofiber) Content(ctx interface{}, getPanelFn types.GetPanelFn, fn context.NodeProcessor, btns ...types.Button) { |
|
gof.GetContent(ctx, getPanelFn, gof, btns, fn) |
|
} |
|
|
|
|
|
func (gof *Gofiber) SetApp(app interface{}) error { |
|
var ( |
|
eng *fiber.App |
|
ok bool |
|
) |
|
if eng, ok = app.(*fiber.App); !ok { |
|
return errors.New("fiber.App adapter SetApp: wrong parameter") |
|
} |
|
|
|
gof.app = eng |
|
return nil |
|
} |
|
|
|
|
|
func (gof *Gofiber) AddHandler(method, path string, handlers context.Handlers) { |
|
|
|
gof.app.Add(strings.ToUpper(method), path, func(c *fiber.Ctx) error { |
|
|
|
httpreq := convertCtx(c.Context()) |
|
ctx := context.NewContext(httpreq) |
|
|
|
for _, key := range c.Route().Params { |
|
if httpreq.URL.RawQuery == "" { |
|
httpreq.URL.RawQuery += strings.ReplaceAll(key, ":", "") + "=" + c.Params(key) |
|
} else { |
|
httpreq.URL.RawQuery += "&" + strings.ReplaceAll(key, ":", "") + "=" + c.Params(key) |
|
} |
|
|
|
} |
|
|
|
ctx.SetHandlers(handlers).Next() |
|
for key, head := range ctx.Response.Header { |
|
c.Set(key, head[0]) |
|
|
|
} |
|
|
|
return c.Status(ctx.Response.StatusCode).SendStream(ctx.Response.Body) |
|
|
|
}) |
|
|
|
} |
|
|
|
func convertCtx(ctx *fasthttp.RequestCtx) *http.Request { |
|
var r http.Request |
|
|
|
body := ctx.PostBody() |
|
r.Method = string(ctx.Method()) |
|
r.Proto = "HTTP/1.1" |
|
r.ProtoMajor = 1 |
|
r.ProtoMinor = 1 |
|
r.RequestURI = string(ctx.RequestURI()) |
|
r.ContentLength = int64(len(body)) |
|
r.Host = string(ctx.Host()) |
|
r.RemoteAddr = ctx.RemoteAddr().String() |
|
|
|
hdr := make(http.Header) |
|
ctx.Request.Header.VisitAll(func(k, v []byte) { |
|
sk := string(k) |
|
sv := string(v) |
|
switch sk { |
|
case "Transfer-Encoding": |
|
r.TransferEncoding = append(r.TransferEncoding, sv) |
|
default: |
|
hdr.Set(sk, sv) |
|
} |
|
}) |
|
r.Header = hdr |
|
r.Body = &netHTTPBody{body} |
|
rURL, err := url.ParseRequestURI(r.RequestURI) |
|
if err != nil { |
|
ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err) |
|
ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError) |
|
return &r |
|
} |
|
r.URL = rURL |
|
return &r |
|
} |
|
|
|
type netHTTPBody struct { |
|
b []byte |
|
} |
|
|
|
func (r *netHTTPBody) Read(p []byte) (int, error) { |
|
if len(r.b) == 0 { |
|
return 0, io.EOF |
|
} |
|
n := copy(p, r.b) |
|
r.b = r.b[n:] |
|
return n, nil |
|
} |
|
|
|
func (r *netHTTPBody) Close() error { |
|
r.b = r.b[:0] |
|
return nil |
|
} |
|
|
|
|
|
func (*Gofiber) Name() string { |
|
return "gofiber" |
|
} |
|
|
|
|
|
func (*Gofiber) SetContext(contextInterface interface{}) adapter.WebFrameWork { |
|
var ( |
|
ctx *fiber.Ctx |
|
ok bool |
|
) |
|
if ctx, ok = contextInterface.(*fiber.Ctx); !ok { |
|
panic("gofiber adapter SetContext: wrong parameter") |
|
} |
|
return &Gofiber{ctx: ctx} |
|
} |
|
|
|
|
|
func (gof *Gofiber) Redirect() { |
|
_ = gof.ctx.Redirect(config.Url(config.GetLoginUrl()), http.StatusFound) |
|
} |
|
|
|
|
|
func (gof *Gofiber) SetContentType() { |
|
gof.ctx.Response().Header.Set("Content-Type", gof.HTMLContentType()) |
|
} |
|
|
|
|
|
func (gof *Gofiber) Write(body []byte) { |
|
_, _ = gof.ctx.Write(body) |
|
} |
|
|
|
|
|
func (gof *Gofiber) GetCookie() (string, error) { |
|
return string(gof.ctx.Cookies(gof.CookieKey())), nil |
|
} |
|
|
|
|
|
func (gof *Gofiber) Lang() string { |
|
return string(gof.ctx.Request().URI().QueryArgs().Peek("__ga_lang")) |
|
} |
|
|
|
|
|
func (gof *Gofiber) Path() string { |
|
return string(gof.ctx.Path()) |
|
} |
|
|
|
|
|
func (gof *Gofiber) Method() string { |
|
return string(gof.ctx.Method()) |
|
} |
|
|
|
|
|
func (gof *Gofiber) FormParam() url.Values { |
|
f, _ := gof.ctx.MultipartForm() |
|
if f != nil { |
|
return f.Value |
|
} |
|
return url.Values{} |
|
} |
|
|
|
|
|
func (gof *Gofiber) IsPjax() bool { |
|
return string(gof.ctx.Request().Header.Peek(constant.PjaxHeader)) == "true" |
|
} |
|
|
|
|
|
func (gof *Gofiber) Query() url.Values { |
|
queryStr := gof.ctx.Context().QueryArgs().QueryString() |
|
queryObj, err := url.Parse(string(queryStr)) |
|
|
|
if err != nil { |
|
return url.Values{} |
|
} |
|
|
|
return queryObj.Query() |
|
} |
|
|
|
|
|
func (gof *Gofiber) Request() *http.Request { |
|
return convertCtx(gof.ctx.Context()) |
|
} |