123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- // package serv_http -- востроенный HTTP-сервер
- package serv_http
- import (
- "fmt"
- "os"
- "time"
- "github.com/gofiber/fiber/v2"
- "github.com/gofiber/fiber/v2/middleware/cache"
- "github.com/gofiber/fiber/v2/middleware/compress"
- "github.com/gofiber/fiber/v2/utils"
- "github.com/gofiber/template/html/v2"
- "git.p78su.freemyip.com/svi/gostore/internal/serv_http/router_anonym"
- "git.p78su.freemyip.com/svi/gostore/pkg/types"
- )
- // ServHttp -- встроенный HTTP-сервер
- type ServHttp struct {
- serv types.IService
- fiberApp *fiber.App
- port string
- store types.IStore
- anonym *router_anonym.RouterAnonym
- }
- // NewServHttp -- возвращает новый HTTP-сервер
- func NewServHttp(serv types.IService) (*ServHttp, error) {
- if serv == nil {
- return nil, fmt.Errorf("NewServHttp(): IService==nil")
- }
- port := os.Getenv("STORE_HTTP_PORT")
- if port == "" {
- return nil, fmt.Errorf("NewServHttp(): env STORE_HTTP_PORT not set")
- }
- engineTmpl := html.New("./static/tmpl", ".tmpl.html")
- appConf := fiber.Config{
- Prefork: false,
- ServerHeader: "GoStore",
- StrictRouting: false,
- CaseSensitive: false,
- Immutable: false,
- UnescapePath: false,
- ETag: false,
- BodyLimit: 10_000_000,
- Concurrency: 0,
- Views: engineTmpl,
- ViewsLayout: "",
- PassLocalsToViews: false,
- ReadTimeout: time.Second * 60,
- WriteTimeout: time.Second * 60,
- IdleTimeout: time.Second * 10,
- ReadBufferSize: 0,
- WriteBufferSize: 0,
- CompressedFileSuffix: ".fiber.gz",
- ProxyHeader: "",
- GETOnly: false,
- // ErrorHandler: func(*fiber.Ctx, error) error { panic("not implemented") },
- DisableKeepalive: false,
- DisableDefaultDate: false,
- DisableDefaultContentType: false,
- DisableHeaderNormalizing: false,
- DisableStartupMessage: false,
- AppName: "GoStore",
- StreamRequestBody: false,
- DisablePreParseMultipartForm: false,
- ReduceMemoryUsage: false,
- // JSONEncoder: func(interface{}) ([]byte, error) { panic("not implemented") },
- // JSONDecoder: func([]byte, interface{}) error { panic("not implemented") },
- // XMLEncoder: func(interface{}) ([]byte, error) { panic("not implemented") },
- Network: "tcp4",
- EnableTrustedProxyCheck: false,
- TrustedProxies: []string{},
- EnableIPValidation: false,
- EnablePrintRoutes: true,
- // ColorScheme: fiber.Colors{
- // Black: "",
- // Red: "",
- // Green: "",
- // Yellow: "",
- // Blue: "",
- // Magenta: "",
- // Cyan: "",
- // White: "",
- // Reset: "",
- // },
- // RequestMethods: []string{},
- EnableSplittingOnParsers: false,
- }
- app := fiber.New(appConf)
- app.Static("/static", "./static")
- compressConf := compress.Config{
- Level: compress.LevelBestCompression,
- }
- app.Use(compress.New(compressConf))
- cacheConf := cache.Config{
- Next: nil,
- Expiration: 30 * time.Minute,
- CacheHeader: "X-Cache",
- CacheControl: true,
- KeyGenerator: func(c *fiber.Ctx) string {
- return utils.CopyString(c.Path())
- },
- ExpirationGenerator: nil,
- StoreResponseHeaders: false,
- Storage: nil,
- MaxBytes: 0,
- Methods: []string{fiber.MethodGet, fiber.MethodHead},
- }
- app.Use(cache.New(cacheConf))
- sf := &ServHttp{
- serv: serv,
- fiberApp: app,
- port: port,
- store: serv.Store(),
- }
- var err error
- sf.anonym, err = router_anonym.NewRouterAnonym(sf)
- if err != nil {
- return nil, err
- }
- sf.fiberApp.Get("/", sf.get)
- sf.fiberApp.Post("/put/:login/:pass/:key", sf.postLogin, sf.postPut)
- sf.fiberApp.Post("/get/:login/:pass/:key", sf.postLogin, sf.postGet)
- sf.fiberApp.Post("/del/:login/:pass/:key", sf.postLogin, sf.postDel)
- sf.fiberApp.Post("/find/:login/:pass/:key", sf.postLogin, sf.postFind)
- return sf, nil
- }
- // Возвращает индексную страницу хранилища
- func (sf *ServHttp) get(ctx *fiber.Ctx) error {
- return ctx.Render("index", fiber.Map{})
- }
- // Service -- возвращает сервис
- func (sf *ServHttp) Service() types.IService {
- return sf.serv
- }
- // FiberApp -- возвращает fiber-приложение
- func (sf *ServHttp) FiberApp() *fiber.App {
- return sf.fiberApp
- }
- type ListValRequest struct {
- Val_ []string `json:"val" form:"val"`
- }
- // postFind -- возвращает список ключей по префиксу
- func (sf *ServHttp) postFind(ctx *fiber.Ctx) error {
- key := ctx.Params("key")
- lstKey, err := sf.store.Find(key)
- if err != nil {
- return fiber.NewError(40, "ServHttp.postFind(): in get keys by prefix from db")
- }
- return ctx.JSON(&ListValRequest{
- Val_: lstKey,
- })
- }
- type ValRequest struct {
- Val_ []byte `json:"val" form:"val"`
- }
- // postDel -- удаляет содержимое ключа
- func (sf *ServHttp) postDel(ctx *fiber.Ctx) error {
- key := ctx.Params("key")
- sf.store.Del(key)
- return nil
- }
- // postGet -- возвращает содержимое ключа
- func (sf *ServHttp) postGet(ctx *fiber.Ctx) error {
- key := ctx.Params("key")
- val, err := sf.store.Get(key)
- if err != nil {
- return fiber.NewError(30, "ServHttp.postGet(): in get val from db")
- }
- return ctx.JSON(&ValRequest{
- Val_: val,
- })
- }
- // postPut -- сохраняет содержимое ключа
- func (sf *ServHttp) postPut(ctx *fiber.Ctx) error {
- key := ctx.Params("key")
- req := &ValRequest{}
- if err := ctx.BodyParser(req); err != nil {
- return fiber.NewError(20, "ServHttp.postPut(): bad FORM")
- }
- err := sf.store.Put(key, req.Val_)
- if err != nil {
- return fiber.NewError(21, "ServHttp.postPut(): in put val on db")
- }
- return nil
- }
- // Run -- запускает веб-сервер в работу
- func (sf *ServHttp) Run() error {
- defer sf.serv.CancelApp()
- err := sf.fiberApp.Listen(":" + sf.port)
- if err != nil {
- return fmt.Errorf("ServHttp.Run(): in listen port(%q), err=\n\t%w", sf.port, err)
- }
- return nil
- }
- // Проверяет логин/пароль в запросе
- func (sf *ServHttp) postLogin(ctx *fiber.Ctx) error {
- // login := ctx.Params("login")
- // if login != sf.login {
- // return fiber.NewError(1, "ServHttp.postLogin(): bad login/pass")
- // }
- // pass := ctx.Params("pass")
- // if pass != sf.pass {
- // return fiber.NewError(2, "ServHttp.postLogin(): bad login/pass")
- // }
- key := ctx.Params("key")
- if key == "" {
- return fiber.NewError(3, "ServHttp.postLogin(): key is empty")
- }
- return ctx.Next()
- }
|